#include "nlws.h"
#include "nlws_perl_loop.h"
#include "xshelper/xshelper.h"
#define DEBUG 0
#if DEBUG
#define LOG_FUNC fprintf(stderr, "%s\n", __func__)
#else
#define LOG_FUNC
#endif
static
int
init_pt_custom (
struct
lws_context *cx,
void
*_loop,
int
tsi) {
LOG_FUNC;
nlws_abstract_loop_t* myloop_p = lws_evlib_tsi_to_evlib_pt(cx, tsi);
nlws_abstract_loop_t *sourceloop_p = _loop;
PERL_CONTEXT_FROM_STRUCT(sourceloop_p);
SV* methargs[] = {
newSVuv( (UV) cx ),
NULL,
};
xsh_call_object_method_void( aTHX_ sourceloop_p->perlobj,
"set_lws_context"
, methargs );
StructCopy(sourceloop_p, myloop_p, nlws_abstract_loop_t);
myloop_p->lws_context = cx;
SvREFCNT_inc(myloop_p->perlobj);
return
0;
}
static
int
custom_io_accept (
struct
lws *wsi) {
LOG_FUNC;
nlws_abstract_loop_t* myloop_p = lws_evlib_wsi_to_evlib_pt(wsi);
PERL_CONTEXT_FROM_STRUCT(myloop_p);
int
fd = lws_get_socket_fd(wsi);
SV* myloop_sv = myloop_p->perlobj;
SV* args[] = { newSViv(fd), NULL };
xsh_call_object_method_void(aTHX_ myloop_sv,
"add_fd"
, args);
return
0;
}
static
void
custom_io (
struct
lws *wsi, unsigned
int
flags) {
LOG_FUNC;
nlws_abstract_loop_t* myloop_p = lws_evlib_wsi_to_evlib_pt(wsi);
int
fd = lws_get_socket_fd(wsi);
if
(-1 != fd) {
PERL_CONTEXT_FROM_STRUCT(myloop_p);
SV* myloop_sv = myloop_p->perlobj;
char
*method_name;
if
(flags & LWS_EV_START) {
method_name =
"add_to_fd"
;
}
else
{
method_name =
"remove_from_fd"
;
}
SV* args[] = {
newSViv(fd),
newSVuv(flags),
NULL,
};
xsh_call_object_method_void(aTHX_ myloop_sv, method_name, args );
}
}
static
int
custom_io_close (
struct
lws *wsi) {
LOG_FUNC;
nlws_abstract_loop_t* myloop_p = lws_evlib_wsi_to_evlib_pt(wsi);
int
fd = lws_get_socket_fd(wsi);
if
(-1 != fd) {
PERL_CONTEXT_FROM_STRUCT(myloop_p);
SV* myloop_sv = myloop_p->perlobj;
SV* args[] = { newSViv(fd), NULL };
xsh_call_object_method_void(aTHX_ myloop_sv,
"remove_fd"
, args);
}
return
0;
}
# if 0
static
void
custom_destroy_wsi (
struct
lws *wsi) {
LOG_FUNC;
nlws_abstract_loop_t* myloop_p = lws_evlib_wsi_to_evlib_pt(wsi);
PERL_CONTEXT_FROM_STRUCT(myloop_p);
}
static
void
custom_destroy_context1 (
struct
lws_context *context) {
LOG_FUNC;
fprintf
(stderr,
"lws_context = %p\n"
, context);
}
static
void
custom_destroy_context2 (
struct
lws_context *context) {
LOG_FUNC;
fprintf
(stderr,
"lws_context = %p\n"
, context);
}
#endif
static
void
custom_destroy_pt (
struct
lws_context *cx,
int
tsi) {
LOG_FUNC;
nlws_abstract_loop_t* myloop_p = lws_evlib_tsi_to_evlib_pt(cx, tsi);
PERL_CONTEXT_FROM_STRUCT(myloop_p);
SvREFCNT_dec(myloop_p->perlobj);
}
const
struct
lws_event_loop_ops event_loop_ops_custom = {
.name =
"net-lws-custom-loop"
,
.init_pt = init_pt_custom,
.init_vhost_listen_wsi = custom_io_accept,
.sock_accept = custom_io_accept,
.io = custom_io,
.wsi_logical_close = custom_io_close,
# if 0
.destroy_wsi = custom_destroy_wsi,
.destroy_context1 = custom_destroy_context1,
.destroy_context2 = custom_destroy_context2,
#endif
.destroy_pt = custom_destroy_pt,
.evlib_size_pt =
sizeof
(nlws_abstract_loop_t),
};
const
lws_plugin_evlib_t evlib_custom = {
.hdr = {
"custom perl loop"
,
"net_lws_plugin"
,
LWS_BUILD_HASH,
LWS_PLUGIN_API_MAGIC,
},
.ops = &event_loop_ops_custom,
};