ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Coro/Coro/CoroAPI.h
Revision: 1.33
Committed: Wed Mar 11 09:47:17 2020 UTC (4 years, 7 months ago) by root
Content type: text/plain
Branch: MAIN
CVS Tags: rel-6_57, HEAD
Changes since 1.32: +15 -3 lines
Log Message:
*** empty log message ***

File Contents

# Content
1 #ifndef CORO_API_H
2 #define CORO_API_H
3
4 #include "EXTERN.h"
5 #include "perl.h"
6 #include "XSUB.h"
7
8 #ifndef pTHX_
9 # define pTHX_
10 # define aTHX_
11 # define pTHX
12 # define aTHX
13 #endif
14
15 /* C-level coroutine struct, opaque, not used much */
16 struct coro;
17
18 /* used for schedule-like-function prepares */
19 struct coro_transfer_args
20 {
21 struct coro *prev, *next;
22 };
23
24 /* this is the per-perl-coro slf frame info
25 * it is treated like other "global" interpreter data
26 * and unfortunately is copied around, so keep it small
27 *
28 * Workflow:
29 *
30 * 1. init function is called to parse arguments and fill out the CoroSLF frame
31 * 2. loop starts by calling frame->prepare, providing transfer arguments
32 * 3. transfer is called, transsferring control to another coro
33 * 4. if at this point, the coro is destroyed: frame->destroy is called, then no further processing
34 * 5. otherwise: eventually control is transferred back to coro
35 * 6. frame->check is called
36 * 7. check returns 0 => wait not finished, loop to 2
37 * 8. otherwise, check puts results on stack, returns 1 => finish
38 */
39 struct CoroSLF
40 {
41 void (*prepare) (pTHX_ struct coro_transfer_args *ta); /* 0 means not yet initialised */
42 int (*check) (pTHX_ struct CoroSLF *frame);
43 void *data; /* for use by prepare/check/destroy */
44 void (*destroy) (pTHX_ struct CoroSLF *frame);
45 };
46
47 /* needs to fill in the *frame */
48 typedef void (*coro_slf_cb) (pTHX_ struct CoroSLF *frame, CV *cv, SV **arg, int items);
49
50 /* called on enter/leave */
51 typedef void (*coro_enterleave_hook) (pTHX_ void *arg);
52
53 /* private structure, always use the provided macros below */
54 struct CoroAPI
55 {
56 /* private */
57 I32 ver;
58 I32 rev;
59 #define CORO_API_VERSION 7 /* reorder CoroSLF on change */
60 #define CORO_API_REVISION 2
61
62 /* Coro */
63 int nready;
64 SV *current;
65 SV *except;
66 void (*readyhook) (void);
67
68 void (*schedule) (pTHX);
69 void (*schedule_to) (pTHX_ SV *coro_sv);
70 int (*cede) (pTHX);
71 int (*cede_notself) (pTHX);
72 int (*ready) (pTHX_ SV *coro_sv);
73 int (*is_ready) (pTHX_ SV *coro_sv);
74
75 /* Coro::State */
76 void (*transfer) (pTHX_ SV *prev_sv, SV *next_sv); /* Coro::State */
77
78 /* SLF */
79 struct coro *(*sv_state) (pTHX_ SV *coro_sv);
80 void (*execute_slf) (pTHX_ CV *cv, coro_slf_cb init_cb, I32 ax);
81
82 /* public */
83 /* for use as CoroSLF.prepare */
84 void (*prepare_nop) (pTHX_ struct coro_transfer_args *ta);
85 void (*prepare_schedule) (pTHX_ struct coro_transfer_args *ta);
86 void (*prepare_cede) (pTHX_ struct coro_transfer_args *ta);
87 void (*prepare_cede_notself) (pTHX_ struct coro_transfer_args *ta);
88
89 /* private */
90 void (*enterleave_hook)(pTHX_ SV *coro_sv, coro_enterleave_hook enter, void *enter_arg, coro_enterleave_hook leave, void *leave_arg);
91 void (*enterleave_unhook)(pTHX_ SV *coro_sv, coro_enterleave_hook enter, coro_enterleave_hook leave);
92 void (*enterleave_scope_hook)(pTHX_ coro_enterleave_hook enter, void *enter_arg, coro_enterleave_hook leave, void *leave_arg); /* XS caller must LEAVE/ENTER */
93 };
94
95 static struct CoroAPI *GCoroAPI;
96
97 /* public API macros */
98 #define CORO_TRANSFER(prev,next) GCoroAPI->transfer (aTHX_ (prev), (next))
99
100 #define CORO_SV_STATE(coro) GCoroAPI->sv_state (aTHX_ (coro))
101 #define CORO_EXECUTE_SLF(cv,init,ax) GCoroAPI->execute_slf (aTHX_ (cv), (init), (ax))
102 #define CORO_EXECUTE_SLF_XS(init) CORO_EXECUTE_SLF (cv, (init), ax)
103
104 #define CORO_SCHEDULE GCoroAPI->schedule (aTHX)
105 #define CORO_CEDE GCoroAPI->cede (aTHX)
106 #define CORO_CEDE_NOTSELF GCoroAPI->cede_notself (aTHX)
107 #define CORO_READY(coro) GCoroAPI->ready (aTHX_ coro)
108 #define CORO_IS_READY(coro) GCoroAPI->is_ready (coro)
109 #define CORO_NREADY (GCoroAPI->nready)
110 #define CORO_THROW (GCoroAPI->except)
111 #define CORO_CURRENT SvRV (GCoroAPI->current)
112 #define CORO_READYHOOK (GCoroAPI->readyhook)
113
114 #define CORO_ENTERLEAVE_HOOK(coro,enter,enter_arg,leave,leave_arg) GCoroAPI->enterleave_hook (aTHX_ coro, enter, enter_arg, leave, leave_arg)
115 #define CORO_ENTERLEAVE_UNHOOK(coro,enter,leave) GCoroAPI->enterleave_hook (aTHX_ coro, enter , leave )
116 #define CORO_ENTERLEAVE_SCOPE_HOOK(enter,enter_arg,leave,leave_arg) GCoroAPI->enterleave_scope_hook (aTHX_ enter, enter_arg, leave, leave_arg)
117
118 #define I_CORO_API(YourName) \
119 STMT_START { \
120 SV *sv = perl_get_sv ("Coro::API", 0); \
121 if (!sv) croak ("Coro::API not found"); \
122 GCoroAPI = (struct CoroAPI*) SvIV (sv); \
123 if (GCoroAPI->ver != CORO_API_VERSION \
124 || GCoroAPI->rev < CORO_API_REVISION) \
125 croak ("Coro::API version mismatch (%d.%d vs. %d.%d) -- please recompile %s", \
126 (int)GCoroAPI->ver, (int)GCoroAPI->rev, CORO_API_VERSION, CORO_API_REVISION, YourName); \
127 } STMT_END
128
129 #endif
130