EV-YACurl
view release on metacpan or search on metacpan
#endif
}
}
#ifdef __GNUC__
# pragma GCC diagnostic pop
#endif
MODULE = EV::YACurl PACKAGE = EV::YACurl
PROTOTYPES: DISABLE
BOOT:
{
MY_CXT_INIT;
MY_CXT.curlopt = newHV();
MY_CXT.default_priority = 0;
MY_CXT.in_data_callback = 0;
MY_CXT.client_stash = gv_stashpv("EV::YACurl", GV_ADD);
MY_CXT.response_stash = gv_stashpv("EV::YACurl::Response", GV_ADD);
fill_hv_with_constants(aTHX_ MY_CXT.curlopt);
I_EV_API("EV::YACurl");
curl_global_init(CURL_GLOBAL_ALL);
}
void
CLONE(...)
CODE:
MY_CXT_CLONE;
MY_CXT.curlopt = newHV();
MY_CXT.in_data_callback = 0;
MY_CXT.client_stash = gv_stashpv("EV::YACurl", GV_ADD);
MY_CXT.response_stash = gv_stashpv("EV::YACurl::Response", GV_ADD);
fill_hv_with_constants(aTHX_ MY_CXT.curlopt);
void
new(class, args)
SV *class
HV *args
PPCODE:
dMY_CXT;
EV__YACurl *client;
struct ev_loop *loop = EV_DEFAULT;
if (!loop)
croak("EV has no default loop");
Newxz(client, 1, EV__YACurl);
ST(0) = sv_newmortal();
sv_setref_pv(ST(0), SvPV_nolen(class), (void *)client);
client->loop = loop;
client->priority = MY_CXT.default_priority;
client->timer.client = client;
ev_timer_init(&client->timer.timer, yacurl_timer_cb, 0., 0.);
ev_set_priority(&client->timer.timer, client->priority);
/* Weak, so the client is not kept alive by its own curl callbacks. */
client->weak_self_ref = newSVsv(ST(0));
sv_rvweaken(client->weak_self_ref);
client->multi = curl_multi_init();
if (!client->multi)
croak("Failed to instantiate CURLM object");
curl_multi_setopt(client->multi, CURLMOPT_SOCKETFUNCTION, mcurl_socket_callback);
curl_multi_setopt(client->multi, CURLMOPT_TIMERFUNCTION, mcurl_timer_callback);
curl_multi_setopt(client->multi, CURLMOPT_SOCKETDATA, (void *)client);
curl_multi_setopt(client->multi, CURLMOPT_TIMERDATA, (void *)client);
apply_multi_options(aTHX_ aMY_CXT_ client, args);
XSRETURN(1);
void
request(self, callback, options)
SV *self
SV *callback
HV *options
CODE:
dMY_CXT;
EV__YACurl *client;
EV__YACurl__Response *response_ctx;
if (MY_CXT.in_data_callback)
croak("request() cannot be called from a data callback; "
"start follow-up requests from the completion callback");
client = SV_TO_CLIENT(self);
CURL *easy;
CURLMcode error;
HE *iterentry;
if (!SvROK(callback) || SvTYPE(SvRV(callback)) != SVt_PVCV)
croak("request() needs a code reference as its callback");
/* Mortal until curl_multi_add_handle() succeeds, so an intervening
* croak() still frees everything allocated so far. */
Newxz(response_ctx, 1, EV__YACurl__Response);
response_ctx->self_rv = sv_newmortal();
sv_setref_pv(response_ctx->self_rv, "EV::YACurl::Response", (void *)response_ctx);
easy = curl_easy_init();
if (!easy)
croak("Failed to instantiate CURL object");
response_ctx->easy = easy;
if (curl_easy_setopt(easy, CURLOPT_PRIVATE, response_ctx) != CURLE_OK)
croak("Failed to setup CURL object");
curl_easy_setopt(easy, CURLOPT_ERRORBUFFER, response_ctx->errbuf);
response_ctx->held_references = newAV();
response_ctx->callback = newSVsv(callback);
/* Pins the client for as long as the request lives. */
av_push(response_ctx->held_references, newSVsv(self));
( run in 1.078 second using v1.01-cache-2.11-cpan-14f38c9f855 )