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 |
struct CoroSLF |
25 |
{ |
26 |
void (*init) (pTHX_ SV **arg, int items); /* returns CORO_SLF_* */ |
27 |
void (*prepare) (struct coro_transfer_args *ta); |
28 |
int (*check) (pTHX); /* returns repeat-flag, may be zero */ |
29 |
}; |
30 |
|
31 |
/* private structure, always use the provided macros below */ |
32 |
struct CoroAPI |
33 |
{ |
34 |
I32 ver; |
35 |
I32 rev; |
36 |
#define CORO_API_VERSION 7 |
37 |
#define CORO_API_REVISION 0 |
38 |
|
39 |
/* Coro */ |
40 |
int nready; |
41 |
SV *current; |
42 |
void (*readyhook) (void); |
43 |
|
44 |
void (*schedule) (pTHX); |
45 |
int (*cede) (pTHX); |
46 |
int (*cede_notself) (pTHX); |
47 |
int (*ready) (pTHX_ SV *coro_sv); |
48 |
int (*is_ready) (pTHX_ SV *coro_sv); |
49 |
|
50 |
/* Coro::State */ |
51 |
void (*transfer) (pTHX_ SV *prev_sv, SV *next_sv); /* Coro::State */ |
52 |
void (*execute_slf) (pTHX_ CV *cv, const struct CoroSLF *slf, SV **arg, int nitems); |
53 |
struct coro *(*sv_state) (pTHX_ SV *coro); |
54 |
void *slf_data; |
55 |
}; |
56 |
|
57 |
static struct CoroAPI *GCoroAPI; |
58 |
|
59 |
/* public API macros */ |
60 |
#define CORO_TRANSFER(prev,next) GCoroAPI->transfer (aTHX_ (prev), (next)) |
61 |
#define CORO_SCHEDULE GCoroAPI->schedule (aTHX) |
62 |
#define CORO_CEDE GCoroAPI->cede (aTHX) |
63 |
#define CORO_CEDE_NOTSELF GCoroAPI->cede_notself (aTHX) |
64 |
#define CORO_READY(coro) GCoroAPI->ready (aTHX_ coro) |
65 |
#define CORO_IS_READY(coro) GCoroAPI->is_ready (coro) |
66 |
#define CORO_NREADY (GCoroAPI->nready) |
67 |
#define CORO_CURRENT (SvRV (GCoroAPI->current)) |
68 |
#define CORO_READYHOOK (GCoroAPI->readyhook) |
69 |
|
70 |
#define CORO_EXECUTE_SLF(cv,slf,arg,nitems) GCoroAPI->execute_slf (aTHX_ (cv), &(slf), (arg), (nitems)) |
71 |
#define CORO_EXECUTE_SLF_XS(slf) CORO_EXECUTE_SLF (cv, (slf), &ST (0), nitems) |
72 |
|
73 |
#define CORO_SV_STATE(coro) GCoroAPI->sv_state (aTHX_ (coro)) |
74 |
|
75 |
#define CORO_SLF_DATA (GCoroAPI->slf_data) |
76 |
|
77 |
#define I_CORO_API(YourName) \ |
78 |
STMT_START { \ |
79 |
SV *sv = perl_get_sv ("Coro::API", 0); \ |
80 |
if (!sv) croak ("Coro::API not found"); \ |
81 |
GCoroAPI = (struct CoroAPI*) SvIV (sv); \ |
82 |
if (GCoroAPI->ver != CORO_API_VERSION \ |
83 |
|| GCoroAPI->rev < CORO_API_REVISION) \ |
84 |
croak ("Coro::API version mismatch (%d.%d vs. %d.%d) -- please recompile %s", \ |
85 |
GCoroAPI->ver, GCoroAPI->rev, CORO_API_VERSION, CORO_API_REVISION, YourName); \ |
86 |
} STMT_END |
87 |
|
88 |
#endif |
89 |
|