fix deadlock on event plugin

This commit is contained in:
Ron Pedde 2006-05-05 07:38:13 +00:00
parent c29f829c31
commit 5de59a26aa
4 changed files with 104 additions and 13 deletions

View File

@ -135,6 +135,7 @@ void txt_add(char *txtrecord, char *fmt, ...) {
} }
void main_handler(WS_CONNINFO *pwsc) { void main_handler(WS_CONNINFO *pwsc) {
DPRINTF(E_DBG,L_MAIN,"in main_handler\n");
if(plugin_url_candispatch(pwsc)) { if(plugin_url_candispatch(pwsc)) {
DPRINTF(E_DBG,L_MAIN,"Dispatching %s to plugin\n",pwsc->uri); DPRINTF(E_DBG,L_MAIN,"Dispatching %s to plugin\n",pwsc->uri);
plugin_url_handle(pwsc); plugin_url_handle(pwsc);
@ -146,6 +147,7 @@ void main_handler(WS_CONNINFO *pwsc) {
} }
int main_auth(WS_CONNINFO *pwsc, char *username, char *password) { int main_auth(WS_CONNINFO *pwsc, char *username, char *password) {
DPRINTF(E_DBG,L_MAIN,"in main_auth\n");
if(plugin_url_candispatch(pwsc)) { if(plugin_url_candispatch(pwsc)) {
DPRINTF(E_DBG,L_MAIN,"Dispatching auth for %s to plugin\n",pwsc->uri); DPRINTF(E_DBG,L_MAIN,"Dispatching auth for %s to plugin\n",pwsc->uri);
return plugin_auth_handle(pwsc,username,password); return plugin_auth_handle(pwsc,username,password);

View File

@ -56,6 +56,7 @@ typedef struct tag_pluginentry {
} PLUGIN_ENTRY; } PLUGIN_ENTRY;
/* Globals */ /* Globals */
static pthread_key_t _plugin_lock_key;
static PLUGIN_ENTRY _plugin_list; static PLUGIN_ENTRY _plugin_list;
static int _plugin_initialized = 0; static int _plugin_initialized = 0;
@ -72,6 +73,7 @@ void _plugin_readlock(void);
void _plugin_writelock(void); void _plugin_writelock(void);
void _plugin_unlock(void); void _plugin_unlock(void);
int _plugin_error(char **pe, int error, ...); int _plugin_error(char **pe, int error, ...);
void _plugin_free(int *pi);
/* webserver helpers */ /* webserver helpers */
char *pi_ws_uri(WS_CONNINFO *pwsc); char *pi_ws_uri(WS_CONNINFO *pwsc);
@ -127,9 +129,19 @@ PLUGIN_INPUT_FN pi = {
*/ */
int plugin_init(void) { int plugin_init(void) {
pthread_rwlock_init(&_plugin_lock,NULL); pthread_rwlock_init(&_plugin_lock,NULL);
pthread_key_create(&_plugin_lock_key, (void*)_plugin_free);
return TRUE; return TRUE;
} }
/**
* free the tls
*/
void _plugin_free(int *pi) {
if(pi)
free(pi);
}
/** /**
* deinitialize stuff for plugins * deinitialize stuff for plugins
* *
@ -141,14 +153,39 @@ int plugin_deinit(void) {
/** /**
* lock the plugin_mutex * lock the plugin_mutex. As it turns out, there might be one thread that calls
* multiple plug-ins. So we need to be able to just get one readlock, rather than
* multiple. so we'll keep a tls counter.
*
* NO DPRINTFING IN HERE!
*/ */
void _plugin_readlock(void) { void _plugin_readlock(void) {
int err; int err;
int *current_count;
current_count = pthread_getspecific(_plugin_lock_key);
if(!current_count) {
current_count = (int*)malloc(sizeof(int));
if(!current_count) {
/* hrm */
DPRINTF(E_FATAL,L_PLUG,"Malloc error in _plugin_readlock\n");
}
*current_count = 0;
}
DPRINTF(E_DBG,L_PLUG,"Current lock level: %d\n",*current_count);
if(!(*current_count)) {
(*current_count)++;
pthread_setspecific(_plugin_lock_key,(void*)current_count);
if((err=pthread_rwlock_rdlock(&_plugin_lock))) { if((err=pthread_rwlock_rdlock(&_plugin_lock))) {
DPRINTF(E_FATAL,L_PLUG,"cannot lock plugin lock: %s\n",strerror(err)); DPRINTF(E_FATAL,L_PLUG,"cannot lock plugin lock: %s\n",strerror(err));
} }
} else {
(*current_count)++;
pthread_setspecific(_plugin_lock_key,(void*)current_count);
}
} }
/** /**
@ -156,10 +193,31 @@ void _plugin_readlock(void) {
*/ */
void _plugin_writelock(void) { void _plugin_writelock(void) {
int err; int err;
int *current_count;
current_count = pthread_getspecific(_plugin_lock_key);
if(!current_count) {
current_count = (int*)malloc(sizeof(int));
if(!current_count) {
DPRINTF(E_FATAL,L_PLUG,"Malloc error in _plugin_readlock\n");
}
*current_count = 0;
}
DPRINTF(E_DBG,L_PLUG,"Current lock level: %d\n",*current_count);
if(!(*current_count)) {
(*current_count)++;
pthread_setspecific(_plugin_lock_key,(void*)current_count);
if((err=pthread_rwlock_wrlock(&_plugin_lock))) { if((err=pthread_rwlock_wrlock(&_plugin_lock))) {
DPRINTF(E_FATAL,L_PLUG,"cannot lock plugin lock: %s\n",strerror(err)); DPRINTF(E_FATAL,L_PLUG,"cannot lock plugin lock: %s\n",strerror(err));
} }
} else {
(*current_count)++;
pthread_setspecific(_plugin_lock_key,(void*)current_count);
}
} }
/** /**
@ -167,10 +225,23 @@ void _plugin_writelock(void) {
*/ */
void _plugin_unlock(void) { void _plugin_unlock(void) {
int err; int err;
int *current_count;
current_count = pthread_getspecific(_plugin_lock_key);
if(!current_count) {
DPRINTF(E_FATAL,L_PLUG,"_plug_unlock without tls. wtf?\n");
}
(*current_count)--;
if(!(*current_count)) {
pthread_setspecific(_plugin_lock_key,(void*)current_count);
if((err=pthread_rwlock_unlock(&_plugin_lock))) { if((err=pthread_rwlock_unlock(&_plugin_lock))) {
DPRINTF(E_FATAL,L_PLUG,"cannot unlock plugin lock: %s\n",strerror(err)); DPRINTF(E_FATAL,L_PLUG,"cannot unlock plugin lock: %s\n",strerror(err));
} }
} else {
pthread_setspecific(_plugin_lock_key,(void*)current_count);
}
} }
/** /**
@ -270,6 +341,8 @@ int plugin_load(char **pe, char *path) {
int plugin_url_candispatch(WS_CONNINFO *pwsc) { int plugin_url_candispatch(WS_CONNINFO *pwsc) {
PLUGIN_ENTRY *ppi; PLUGIN_ENTRY *ppi;
DPRINTF(E_DBG,L_PLUG,"Entering candispatch\n");
_plugin_readlock(); _plugin_readlock();
ppi = _plugin_list.next; ppi = _plugin_list.next;
while(ppi) { while(ppi) {
@ -279,8 +352,8 @@ int plugin_url_candispatch(WS_CONNINFO *pwsc) {
_plugin_unlock(); _plugin_unlock();
return TRUE; return TRUE;
} }
ppi = ppi->next;
} }
ppi = ppi->next;
} }
_plugin_unlock(); _plugin_unlock();
return FALSE; return FALSE;
@ -417,12 +490,15 @@ int plugin_auth_handle(WS_CONNINFO *pwsc, char *username, char *pw) {
void plugin_event_dispatch(int event_id, int intval, void *vp, int len) { void plugin_event_dispatch(int event_id, int intval, void *vp, int len) {
PLUGIN_ENTRY *ppi; PLUGIN_ENTRY *ppi;
_plugin_readlock(); fprintf(stderr,"entering plugin_event_dispatch\n");
// _plugin_readlock();
ppi = _plugin_list.next; ppi = _plugin_list.next;
while(ppi) { while(ppi) {
fprintf(stderr,"Checking %s\n",ppi->versionstring);
if(ppi->type & PLUGIN_EVENT) { if(ppi->type & PLUGIN_EVENT) {
DPRINTF(E_DBG,L_PLUG,"Dispatching event %d to %s\n", /* DPRINTF(E_DBG,L_PLUG,"Dispatching event %d to %s\n",
event_id,ppi->versionstring); event_id,ppi->versionstring); */
if((ppi->event_fns) && (ppi->event_fns->handler)) { if((ppi->event_fns) && (ppi->event_fns->handler)) {
ppi->event_fns->handler(event_id, intval, vp, len); ppi->event_fns->handler(event_id, intval, vp, len);
@ -430,7 +506,7 @@ void plugin_event_dispatch(int event_id, int intval, void *vp, int len) {
} }
ppi=ppi->next; ppi=ppi->next;
} }
_plugin_unlock(); // _plugin_unlock();
} }

View File

@ -48,7 +48,7 @@ void plugin_handler(int event_id, int intval, void *vp, int len) {
pmsg = (PLUGIN_MSG*)malloc(total_len); pmsg = (PLUGIN_MSG*)malloc(total_len);
if(!pmsg) { if(!pmsg) {
infn->log(E_LOG,"Malloc error in w32-event.c/plugin_handler\n"); // infn->log(E_LOG,"Malloc error in w32-event.c/plugin_handler\n");
return; return;
} }

View File

@ -64,7 +64,20 @@ ShowInstDetails show
ShowUnInstDetails show ShowUnInstDetails show
Section -Pre Section -Pre
nsSCM::QueryStatus "${PRODUCT_NAME}"
Pop $0
Pop $1
StrCmp $0 "success" lbl_stop_service
goto lbl_continue
lbl_stop_service:
DetailPrint "Stopping Service..."
nsSCM::Stop "${PRODUCT_NAME}" nsSCM::Stop "${PRODUCT_NAME}"
Sleep 3000
lbl_continue:
; should really loop until service stops...
!include WinMessages.nsh !include WinMessages.nsh
FindWindow $0 "" "Configuration" FindWindow $0 "" "Configuration"