+++ /dev/null
-/*
- perl-sources.c : irssi
-
- Copyright (C) 1999-2001 Timo Sirainen
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-*/
-
-#define NEED_PERL_H
-#include "module.h"
-#include "signals.h"
-
-#include "perl-core.h"
-#include "perl-common.h"
-#include "perl-sources.h"
-
-typedef struct {
- PERL_SCRIPT_REC *script;
- int tag;
- int refcount;
- int once; /* run only once */
-
- SV *func;
- SV *data;
-} PERL_SOURCE_REC;
-
-static GSList *perl_sources;
-
-static void perl_source_ref(PERL_SOURCE_REC *rec)
-{
- rec->refcount++;
-}
-
-static int perl_source_unref(PERL_SOURCE_REC *rec)
-{
- if (--rec->refcount != 0)
- return TRUE;
-
- SvREFCNT_dec(rec->data);
- SvREFCNT_dec(rec->func);
- g_free(rec);
- return FALSE;
-}
-
-static void perl_source_destroy(PERL_SOURCE_REC *rec)
-{
- perl_sources = g_slist_remove(perl_sources, rec);
-
- g_source_remove(rec->tag);
- rec->tag = -1;
-
- perl_source_unref(rec);
-}
-
-static int perl_source_event(PERL_SOURCE_REC *rec)
-{
- dSP;
- int retcount;
-
- ENTER;
- SAVETMPS;
-
- PUSHMARK(SP);
- XPUSHs(sv_mortalcopy(rec->data));
- PUTBACK;
-
- perl_source_ref(rec);
- retcount = perl_call_sv(rec->func, G_EVAL|G_SCALAR);
- SPAGAIN;
-
- if (SvTRUE(ERRSV)) {
- char *error = g_strdup(SvPV(ERRSV, PL_na));
- signal_emit("script error", 2, rec->script, error);
- g_free(error);
- }
-
- if (perl_source_unref(rec) && rec->once)
- perl_source_destroy(rec);
-
- PUTBACK;
- FREETMPS;
- LEAVE;
-
- return 1;
-}
-
-int perl_timeout_add(int msecs, SV *func, SV *data, int once)
-{
- PERL_SCRIPT_REC *script;
- PERL_SOURCE_REC *rec;
- const char *pkg;
-
- pkg = perl_get_package();
- script = perl_script_find_package(pkg);
- g_return_val_if_fail(script != NULL, -1);
-
- 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);
- rec->tag = g_timeout_add(msecs, (GSourceFunc) perl_source_event, rec);
-
- perl_sources = g_slist_append(perl_sources, rec);
- return rec->tag;
-}
-
-int perl_input_add(int source, int condition, SV *func, SV *data, int once)
-{
- PERL_SCRIPT_REC *script;
- PERL_SOURCE_REC *rec;
- GIOChannel *channel;
- const char *pkg;
-
- pkg = perl_get_package();
- script = perl_script_find_package(pkg);
- g_return_val_if_fail(script != NULL, -1);
-
- 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);
-
- channel = g_io_channel_unix_new(source);
- rec->tag = g_input_add(channel, condition,
- (GInputFunction) perl_source_event, rec);
- g_io_channel_unref(channel);
-
- perl_sources = g_slist_append(perl_sources, rec);
- return rec->tag;
-}
-
-void perl_source_remove(int tag)
-{
- GSList *tmp;
-
- for (tmp = perl_sources; tmp != NULL; tmp = tmp->next) {
- PERL_SOURCE_REC *rec = tmp->data;
-
- if (rec->tag == tag) {
- perl_source_destroy(rec);
- break;
- }
- }
-}
-
-void perl_source_remove_script(PERL_SCRIPT_REC *script)
-{
- GSList *tmp, *next;
-
- for (tmp = perl_sources; tmp != NULL; tmp = next) {
- PERL_SOURCE_REC *rec = tmp->data;
-
- next = tmp->next;
- if (rec->script == script)
- perl_source_destroy(rec);
- }
-}
-
-void perl_sources_start(void)
-{
- perl_sources = NULL;
-}
-
-void perl_sources_stop(void)
-{
- /* timeouts and input waits */
- while (perl_sources != NULL)
- perl_source_destroy(perl_sources->data);
-}