/
sharedref.pmc
169 lines (105 loc) · 2.67 KB
/
sharedref.pmc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
/*
Copyright (C) 2001-2006, The Perl Foundation.
$Id$
=head1 NAME
src/pmc/sharedref.pmc - Shared PMC Reference
=head1 DESCRIPTION
The vtable functions for the SharedRef base class.
This class wraps locking around PMC access.
All methods not present below get a default body autogenerated inside
C<Parrot::Pmc2c>.
Currently all access is locked. When we have a non-copying GC allocator
we can relax that a bit.
=head2 Methods
=over 4
=cut
*/
#include "parrot/parrot.h"
/*
* TODO we should catch exceptions around these locks
* if the vtable meth throws the lock is never unlocked
*/
#define LOCK_PMC(interp, pmc) LOCK(PMC_sync(pmc)->pmc_lock);
#define UNLOCK_PMC(interp, pmc) UNLOCK(PMC_sync(pmc)->pmc_lock);
pmclass SharedRef does ref need_ext is_shared extends Ref {
void init() {
SUPER();
}
/*
=item C<void init_pmc(PMC *init)>
Initialize the shared reference.
TODO - If the PMC we refer to is an aggregate (or has properties) then:
=over 4
=item *
call C<share()> on the aggregate, which calls C<share()> on its contents
- so getting aggregate members only yields shared PMCs
=item *
and unshare the aggregate itself, because we lock on behalf of the
referee
=back
A direct dereference of the C<SharedRef> is currently not enabled so we
shouldn't leak unshared PMCs into different threads.
=cut
*/
void init_pmc(PMC* initializer) {
SUPER(initializer);
PObj_active_destroy_SET(SELF);
}
/*
=item C<void share()>
We do already sharing - so just ignore.
=cut
*/
void share() {
}
/*
=item C<void mark()>
Marks the reference as live.
=cut
*/
void mark() {
SUPER();
}
/*
=item C<void set_pmc(PMC *other)>
Sets the referenced PMC to C<*other>.
=item C<PMC* get_pmc()>
Catch dereferencing. This would unshare the referred PMC.
=cut
*/
void set_pmc(PMC* other) {
SUPER(other);
PObj_active_destroy_SET(SELF);
}
PMC* get_pmc() {
real_exception(INTERP, NULL, E_ReferenceError,
"deref not allowed");
return NULL;
}
/*
=item C<void destroy()>
Destroys the referred object and itself. This probably needs destroy ordering
or at least a detection if the referred PMC is already destroyed.
=cut
*/
void destroy() {
PMC * const ref = PMC_pmc_val(SELF);
if (PObj_active_destroy_TEST(ref))
VTABLE_destroy(INTERP, ref);
if (PMC_sync(SELF)->owner != INTERP)
PANIC("SharedRef destroyed by wrong interpreter");
SUPER();
}
}
/*
=back
=head1 HISTORY
Initial revision by leo 2004.01.14.
=cut
*/
/*
* Local variables:
* c-file-style: "parrot"
* End:
* vim: expandtab shiftwidth=4:
*/