Fixing a Perl_my_dirfd() related test failure.
[p5sagit/p5-mst-13.2.git] / ext / Thread / Thread.xs
1 #define PERL_NO_GET_CONTEXT
2 #include "EXTERN.h"
3 #include "perl.h"
4 #include "XSUB.h"
5
6 #ifdef __cplusplus
7 #ifdef I_UNISTD
8 #include <unistd.h>
9 #endif
10 #endif
11 #include <fcntl.h>
12                         
13 static int sig_pipe[2];
14             
15 #ifndef THREAD_RET_TYPE
16 #define THREAD_RET_TYPE void *
17 #define THREAD_RET_CAST(x) ((THREAD_RET_TYPE) x)
18 #endif
19
20 static void
21 remove_thread(pTHX_ Thread t)
22 {
23 }
24
25 static THREAD_RET_TYPE
26 threadstart(void *arg)
27 {
28     return THREAD_RET_CAST(NULL);
29 }
30
31 static SV *
32 newthread (pTHX_ SV *startsv, AV *initargs, char *classname)
33 {
34 #ifdef USE_ITHREADS
35     croak("This perl was built for \"ithreads\", which currently does not support Thread.pm.\n"
36           "Run \"perldoc Thread\" for more information");
37 #else
38     croak("This perl was not built with support for 5.005-style threads.\n"
39           "Run \"perldoc Thread\" for more information");
40 #endif
41   return &PL_sv_undef;
42 }
43
44 static Signal_t handle_thread_signal (int sig);
45
46 static Signal_t
47 handle_thread_signal(int sig)
48 {
49     unsigned char c = (unsigned char) sig;
50     dTHX;
51     /*
52      * We're not really allowed to call fprintf in a signal handler
53      * so don't be surprised if this isn't robust while debugging
54      * with -DL.
55      */
56     DEBUG_S(PerlIO_printf(Perl_debug_log,
57             "handle_thread_signal: got signal %d\n", sig));
58     write(sig_pipe[1], &c, 1);
59 }
60
61 MODULE = Thread         PACKAGE = Thread
62 PROTOTYPES: DISABLE
63
64 void
65 new(classname, startsv, ...)
66         char *          classname
67         SV *            startsv
68         AV *            av = av_make(items - 2, &ST(2));
69     PPCODE:
70         XPUSHs(sv_2mortal(newthread(aTHX_ startsv, av, classname)));
71
72 void
73 join(t)
74         Thread  t
75     PREINIT:
76 #ifdef USE_5005THREADS
77         AV *    av;
78         int     i;
79 #endif
80     PPCODE:
81
82 void
83 detach(t)
84         Thread  t
85     CODE:
86
87 void
88 equal(t1, t2)
89         Thread  t1
90         Thread  t2
91     PPCODE:
92         PUSHs((t1 == t2) ? &PL_sv_yes : &PL_sv_no);
93
94 void
95 flags(t)
96         Thread  t
97     PPCODE:
98
99 void
100 done(t)
101         Thread  t
102     PPCODE:
103
104 void
105 self(classname)
106         char *  classname
107     PREINIT:
108 #ifdef USE_5005THREADS
109         SV *sv;
110 #endif
111     PPCODE:        
112
113 U32
114 tid(t)
115         Thread  t
116     CODE:
117         RETVAL = 0;
118     OUTPUT:
119         RETVAL
120
121 void
122 DESTROY(t)
123         SV *    t
124     PPCODE:
125         PUSHs(t ? &PL_sv_yes : &PL_sv_no);
126
127 void
128 yield()
129     CODE:
130
131 void
132 cond_wait(sv)
133         SV *    sv
134 CODE:                       
135
136 void
137 cond_signal(sv)
138         SV *    sv
139 CODE:
140
141 void
142 cond_broadcast(sv)
143         SV *    sv
144 CODE: 
145
146 void
147 list(classname)
148         char *  classname
149     PPCODE:
150
151
152 MODULE = Thread         PACKAGE = Thread::Signal
153
154 void
155 kill_sighandler_thread()
156     PPCODE:
157         write(sig_pipe[1], "\0", 1);
158         PUSHs(&PL_sv_yes);
159
160 void
161 init_thread_signals()
162     PPCODE:
163         PL_sighandlerp = handle_thread_signal;
164         if (pipe(sig_pipe) == -1)
165             XSRETURN_UNDEF;
166         PUSHs(&PL_sv_yes);
167
168 void
169 await_signal()
170     PREINIT:
171         unsigned char c;
172         SSize_t ret;
173     CODE:
174         do {
175             ret = read(sig_pipe[0], &c, 1);
176         } while (ret == -1 && errno == EINTR);
177         if (ret == -1)
178             croak("panic: await_signal");
179         ST(0) = sv_newmortal();
180         if (ret)
181             sv_setsv(ST(0), c ? PL_psig_ptr[c] : &PL_sv_no);
182         DEBUG_S(PerlIO_printf(Perl_debug_log,
183                               "await_signal returning %s\n", SvPEEK(ST(0))));
184
185 MODULE = Thread         PACKAGE = Thread::Specific
186
187 void
188 data(classname = "Thread::Specific")
189         char *  classname
190     PPCODE: