[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Python plugin API locking (patch)
This patch should protect all plugin API functions with a global
recursive mutex.
Regards.
--
Gustavo J. A. M. Carneiro
<gjc@inescporto.pt> <gustavo@users.sourceforge.net>
diff -rup xchat-2.0.5/src/common/plugin.c xchat-2.0.5-gjc/src/common/plugin.c
--- xchat-2.0.5/src/common/plugin.c 2003-09-21 11:28:08.000000000 +0100
+++ xchat-2.0.5-gjc/src/common/plugin.c 2003-10-03 22:23:08.000000000 +0100
@@ -48,6 +47,12 @@ typedef struct session xchat_context;
#define DEBUG(t) PrintText(0,t)
+static GStaticRecMutex xchat_api_lock = G_STATIC_REC_MUTEX_INIT;
+
+#define xchat_plugin_api_lock() g_static_rec_mutex_lock (&xchat_api_lock)
+#define xchat_plugin_api_unlock() g_static_rec_mutex_lock (&xchat_api_lock)
+
+
/* crafted to be an even 32 bytes */
struct _xchat_hook
{
@@ -187,7 +192,9 @@ plugin_list_add (xchat_context *ctx, cha
pl->deinit_callback = deinit_func;
pl->fake = fake;
+ xchat_plugin_api_lock();
plugin_list = g_slist_prepend (plugin_list, pl);
+ xchat_plugin_api_unlock();
return pl;
}
@@ -673,10 +680,12 @@ plugin_show_help (session *sess, char *c
void *
xchat_unhook (xchat_plugin *ph, xchat_hook *hook)
{
+ xchat_plugin_api_lock();
/* perl.c trips this */
- if (hook->type == HOOK_DELETED || !g_slist_find (hook_list, hook))
+ if (hook->type == HOOK_DELETED || !g_slist_find (hook_list, hook)) {
+ xchat_plugin_api_unlock();
return NULL;
-
+ }
if (hook->type == HOOK_TIMER && hook->tag != 0)
fe_timeout_remove (hook->tag);
@@ -690,6 +699,7 @@ xchat_unhook (xchat_plugin *ph, xchat_ho
if (hook->help_text)
free (hook->help_text); /* NULL for non-commands */
+ xchat_plugin_api_unlock();
return hook->userdata;
}
@@ -697,29 +707,49 @@ xchat_hook *
xchat_hook_command (xchat_plugin *ph, char *name, int pri, xchat_cmd_cb *callb,
char *help_text, void *userdata)
{
- return plugin_add_hook (ph, HOOK_COMMAND, pri, name, help_text, callb, 0,
+ xchat_hook *retval;
+
+ xchat_plugin_api_lock();
+ retval = plugin_add_hook (ph, HOOK_COMMAND, pri, name, help_text, callb, 0,
userdata);
+ xchat_plugin_api_unlock();
+ return retval;
}
xchat_hook *
xchat_hook_server (xchat_plugin *ph, char *name, int pri, xchat_serv_cb *callb,
void *userdata)
{
- return plugin_add_hook (ph, HOOK_SERVER, pri, name, 0, callb, 0, userdata);
+ xchat_hook *retval;
+
+ xchat_plugin_api_lock();
+ retval = plugin_add_hook (ph, HOOK_SERVER, pri, name, 0, callb, 0, userdata);
+ xchat_plugin_api_unlock();
+ return retval;
}
xchat_hook *
xchat_hook_print (xchat_plugin *ph, char *name, int pri, xchat_print_cb *callb,
void *userdata)
{
- return plugin_add_hook (ph, HOOK_PRINT, pri, name, 0, callb, 0, userdata);
+ xchat_hook *retval;
+
+ xchat_plugin_api_lock();
+ retval = plugin_add_hook (ph, HOOK_PRINT, pri, name, 0, callb, 0, userdata);
+ xchat_plugin_api_unlock();
+ return retval;
}
xchat_hook *
xchat_hook_timer (xchat_plugin *ph, int timeout, xchat_timer_cb *callb,
void *userdata)
{
- return plugin_add_hook (ph, HOOK_TIMER, 0, 0, 0, callb, timeout, userdata);
+ xchat_hook *retval;
+
+ xchat_plugin_api_lock();
+ retval = plugin_add_hook (ph, HOOK_TIMER, 0, 0, 0, callb, timeout, userdata);
+ xchat_plugin_api_unlock();
+ return retval;
}
xchat_hook *
@@ -728,10 +758,12 @@ xchat_hook_fd (xchat_plugin *ph, int fd,
{
xchat_hook *hook;
+ xchat_plugin_api_lock();
hook = plugin_add_hook (ph, HOOK_FD, 0, 0, 0, callb, 0, userdata);
hook->pri = fd;
/* plugin hook_fd flags correspond exactly to FIA_* flags (fe.h) */
hook->tag = fe_input_add (fd, flags, plugin_fd_cb, hook);
+ xchat_plugin_api_unlock();
return hook;
}
@@ -739,13 +771,16 @@ xchat_hook_fd (xchat_plugin *ph, int fd,
void
xchat_print (xchat_plugin *ph, char *text)
{
+ xchat_plugin_api_lock();
if (!is_session (ph->context))
{
DEBUG("xchat_print called without a valid context.\n");
+ xchat_plugin_api_unlock();
return;
}
PrintText (ph->context, text);
+ xchat_plugin_api_unlock();
}
void
@@ -765,13 +800,16 @@ xchat_printf (xchat_plugin *ph, char *fo
void
xchat_command (xchat_plugin *ph, char *command)
{
+ xchat_plugin_api_lock();
if (!is_session (ph->context))
{
DEBUG("xchat_command called without a valid context.\n");
+ xchat_plugin_api_unlock();
return;
}
handle_command (ph->context, command, FALSE);
+ xchat_plugin_api_unlock();
}
void
@@ -791,7 +829,11 @@ xchat_commandf (xchat_plugin *ph, char *
int
xchat_nickcmp (xchat_plugin *ph, char *s1, char *s2)
{
- return ((session *)ph->context)->server->p_cmp (s1, s2);
+ int rv;
+ xchat_plugin_api_lock();
+ rv = ((session *)ph->context)->server->p_cmp (s1, s2);
+ xchat_plugin_api_unlock();
+ return rv;
}
xchat_context *
@@ -803,11 +845,14 @@ xchat_get_context (xchat_plugin *ph)
int
xchat_set_context (xchat_plugin *ph, xchat_context *context)
{
+ xchat_plugin_api_lock();
if (is_session (context))
{
ph->context = context;
+ xchat_plugin_api_unlock();
return 1;
}
+ xchat_plugin_api_unlock();
return 0;
}
@@ -817,10 +862,13 @@ xchat_find_context (xchat_plugin *ph, ch
GSList *slist, *clist;
server *serv;
session *sess;
+ xchat_context *retval = NULL;
if (servname == NULL && channel == NULL)
return current_sess;
+ xchat_plugin_api_lock();
+
slist = serv_list;
while (slist)
{
@@ -830,8 +878,10 @@ xchat_find_context (xchat_plugin *ph, ch
strcasecmp (servname, serv->hostname) == 0 ||
(serv->networkname && strcasecmp (servname, serv->networkname) == 0))
{
- if (channel == NULL)
- return serv->front_session;
+ if (channel == NULL) {
+ retval = serv->front_session;
+ goto exit;
+ }
clist = sess_list;
while (clist)
@@ -839,27 +889,33 @@ xchat_find_context (xchat_plugin *ph, ch
sess = clist->data;
if (sess->server == serv)
{
- if (rfc_casecmp (channel, sess->channel) == 0)
- return sess;
+ if (rfc_casecmp (channel, sess->channel) == 0) {
+ retval = sess;
+ goto exit;
+ }
}
clist = clist->next;
}
}
slist = slist->next;
}
-
- return NULL;
+exit:
+ xchat_plugin_api_unlock();
+ return retval;
}
const char *
xchat_get_info (xchat_plugin *ph, const char *id)
{
session *sess;
+ const char *retval = NULL;
+ xchat_plugin_api_lock();
sess = ph->context;
if (!is_session (sess))
{
DEBUG("xchat_get_info called without a valid context.\n");
+ xchat_plugin_api_unlock();
return NULL;
}
@@ -867,43 +923,47 @@ xchat_get_info (xchat_plugin *ph, const
{
case 0x2de2ee: /* away */
if (sess->server->is_away)
- return sess->server->last_away_reason;
- return NULL;
+ retval = sess->server->last_away_reason;
+ break;
case 0x2c0b7d03: /* channel */
- return sess->channel;
+ retval = sess->channel; break;
case 0x30f5a8: /* host */
- return sess->server->hostname;
+ retval = sess->server->hostname; break;
case 0x6de15a2e: /* network */
- return sess->server->networkname;
+ retval = sess->server->networkname; break;
case 0x339763: /* nick */
- return sess->server->nick;
+ retval = sess->server->nick; break;
case 0xca022f43: /* server */
- if (!sess->server->connected)
- return NULL;
- return sess->server->servername;
+ if (sess->server->connected)
+ retval = sess->server->servername; break;
case 0x696cd2f: /* topic */
- return sess->topic;
+ retval = sess->topic; break;
case 0x14f51cd8: /* version */
- return VERSION;
+ retval = VERSION; break;
case 0xdd9b1abd: /* xchatdir */
- return get_xdir ();
+ retval = get_xdir (); break;
}
- return NULL;
+ xchat_plugin_api_unlock();
+
+ return retval;
}
int
xchat_get_prefs (xchat_plugin *ph, const char *name, const char **string, int *integer)
{
int i = 0;
+ int retval = 0;
+
+ xchat_plugin_api_lock();
do
{
@@ -913,11 +973,11 @@ xchat_get_prefs (xchat_plugin *ph, const
{
case TYPE_STR:
*string = ((char *) &prefs + vars[i].offset);
- return 1;
+ retval = 1; break;
case TYPE_INT:
*integer = *((int *) &prefs + vars[i].offset);
- return 2;
+ retval = 2; break;
default:
/*case TYPE_BOOL:*/
@@ -925,14 +985,16 @@ xchat_get_prefs (xchat_plugin *ph, const
*integer = 1;
else
*integer = 0;
- return 3;
+ retval = 3;
}
}
i++;
}
while (vars[i].name);
- return 0;
+ xchat_plugin_api_unlock();
+
+ return retval;
}
xchat_list *
@@ -942,6 +1004,7 @@ xchat_list_get (xchat_plugin *ph, const
list = malloc (sizeof (xchat_list));
list->pos = NULL;
+ xchat_plugin_api_lock();
switch (str_hash (name))
{
@@ -970,9 +1033,10 @@ xchat_list_get (xchat_plugin *ph, const
default:
free (list);
- return NULL;
+ list = NULL;
}
+ xchat_plugin_api_unlock();
return list;
}
@@ -1151,9 +1215,11 @@ xchat_plugingui_add (xchat_plugin *ph, c
char *version, char *reserved)
{
#ifdef USE_PLUGIN
+ xchat_plugin_api_lock();
ph = plugin_list_add (NULL, strdup (filename), name, desc, version, NULL,
NULL, TRUE);
fe_pluginlist_update ();
+ xchat_plugin_api_unlock();
#endif
return ph;
@@ -1163,7 +1229,9 @@ void
xchat_plugingui_remove (xchat_plugin *ph, void *handle)
{
#ifdef USE_PLUGIN
+ xchat_plugin_api_lock();
plugin_free (handle, FALSE, FALSE);
+ xchat_plugin_api_unlock();
#endif
}
@@ -1186,8 +1254,10 @@ xchat_emit_print (xchat_plugin *ph, char
break;
}
+ xchat_plugin_api_lock();
i = text_emit_by_name (event_name, ph->context, argv[0], argv[1],
argv[2], argv[3]);
+ xchat_plugin_api_unlock();
va_end (args);
return i;
diff -rup xchat-2.0.5/src/common/xchat.c xchat-2.0.5-gjc/src/common/xchat.c
--- xchat-2.0.5/src/common/xchat.c 2003-09-12 16:15:20.000000000 +0100
+++ xchat-2.0.5-gjc/src/common/xchat.c 2003-10-03 22:25:33.000000000 +0100
@@ -795,6 +795,8 @@ xchat_init (void)
char buf[2048];
const char *cs = NULL;
+ if (!g_thread_supported ()) g_thread_init (NULL);
+
#ifdef WIN32
WSADATA wsadata;