typedef struct {
PERL_SCRIPT_REC *script;
int tag;
- int refcount;
+ int refcount;
+ int once; /* run only once */
SV *func;
SV *data;
rec->refcount++;
}
-static void perl_source_unref(PERL_SOURCE_REC *rec)
+static int perl_source_unref(PERL_SOURCE_REC *rec)
{
if (--rec->refcount != 0)
- return;
+ return TRUE;
SvREFCNT_dec(rec->data);
SvREFCNT_dec(rec->func);
g_free(rec);
+ return FALSE;
}
static void perl_source_destroy(PERL_SOURCE_REC *rec)
static int perl_source_event(PERL_SOURCE_REC *rec)
{
dSP;
+ int retcount;
ENTER;
SAVETMPS;
PUTBACK;
perl_source_ref(rec);
- perl_call_sv(rec->func, G_EVAL|G_DISCARD);
+ retcount = perl_call_sv(rec->func, G_EVAL|G_SCALAR);
SPAGAIN;
if (SvTRUE(ERRSV)) {
signal_emit("script error", 2, rec->script, error);
g_free(error);
}
- perl_source_unref(rec);
+
+ if (perl_source_unref(rec) && rec->once)
+ perl_source_destroy(rec);
PUTBACK;
FREETMPS;
return 1;
}
-int perl_timeout_add(int msecs, SV *func, SV *data)
+int perl_timeout_add(int msecs, SV *func, SV *data, int once)
{
PERL_SCRIPT_REC *script;
PERL_SOURCE_REC *rec;
rec = g_new0(PERL_SOURCE_REC, 1);
perl_source_ref(rec);
- rec->script = script;
+ rec->once = once;
+ rec->script = script;
rec->func = perl_func_sv_inc(func, pkg);
rec->data = SvREFCNT_inc(data);
rec->tag = g_timeout_add(msecs, (GSourceFunc) perl_source_event, rec);
return rec->tag;
}
-int perl_input_add(int source, int condition, SV *func, SV *data)
+int perl_input_add(int source, int condition, SV *func, SV *data, int once)
{
PERL_SCRIPT_REC *script;
PERL_SOURCE_REC *rec;
rec = g_new0(PERL_SOURCE_REC, 1);
perl_source_ref(rec);
+ rec->once = once;
rec->script =script;
rec->func = perl_func_sv_inc(func, pkg);
rec->data = SvREFCNT_inc(data);