fix deadlock on event plugin
This commit is contained in:
parent
c29f829c31
commit
5de59a26aa
|
@ -135,6 +135,7 @@ void txt_add(char *txtrecord, char *fmt, ...) {
|
|||
}
|
||||
|
||||
void main_handler(WS_CONNINFO *pwsc) {
|
||||
DPRINTF(E_DBG,L_MAIN,"in main_handler\n");
|
||||
if(plugin_url_candispatch(pwsc)) {
|
||||
DPRINTF(E_DBG,L_MAIN,"Dispatching %s to plugin\n",pwsc->uri);
|
||||
plugin_url_handle(pwsc);
|
||||
|
@ -146,6 +147,7 @@ void main_handler(WS_CONNINFO *pwsc) {
|
|||
}
|
||||
|
||||
int main_auth(WS_CONNINFO *pwsc, char *username, char *password) {
|
||||
DPRINTF(E_DBG,L_MAIN,"in main_auth\n");
|
||||
if(plugin_url_candispatch(pwsc)) {
|
||||
DPRINTF(E_DBG,L_MAIN,"Dispatching auth for %s to plugin\n",pwsc->uri);
|
||||
return plugin_auth_handle(pwsc,username,password);
|
||||
|
|
100
src/plugin.c
100
src/plugin.c
|
@ -56,6 +56,7 @@ typedef struct tag_pluginentry {
|
|||
} PLUGIN_ENTRY;
|
||||
|
||||
/* Globals */
|
||||
static pthread_key_t _plugin_lock_key;
|
||||
static PLUGIN_ENTRY _plugin_list;
|
||||
static int _plugin_initialized = 0;
|
||||
|
||||
|
@ -72,6 +73,7 @@ void _plugin_readlock(void);
|
|||
void _plugin_writelock(void);
|
||||
void _plugin_unlock(void);
|
||||
int _plugin_error(char **pe, int error, ...);
|
||||
void _plugin_free(int *pi);
|
||||
|
||||
/* webserver helpers */
|
||||
char *pi_ws_uri(WS_CONNINFO *pwsc);
|
||||
|
@ -127,9 +129,19 @@ PLUGIN_INPUT_FN pi = {
|
|||
*/
|
||||
int plugin_init(void) {
|
||||
pthread_rwlock_init(&_plugin_lock,NULL);
|
||||
pthread_key_create(&_plugin_lock_key, (void*)_plugin_free);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* free the tls
|
||||
*/
|
||||
void _plugin_free(int *pi) {
|
||||
if(pi)
|
||||
free(pi);
|
||||
}
|
||||
|
||||
/**
|
||||
* deinitialize stuff for plugins
|
||||
*
|
||||
|
@ -141,13 +153,38 @@ 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) {
|
||||
int err;
|
||||
int *current_count;
|
||||
|
||||
if((err=pthread_rwlock_rdlock(&_plugin_lock))) {
|
||||
DPRINTF(E_FATAL,L_PLUG,"cannot lock plugin lock: %s\n",strerror(err));
|
||||
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))) {
|
||||
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,9 +193,30 @@ void _plugin_readlock(void) {
|
|||
*/
|
||||
void _plugin_writelock(void) {
|
||||
int err;
|
||||
int *current_count;
|
||||
|
||||
if((err=pthread_rwlock_wrlock(&_plugin_lock))) {
|
||||
DPRINTF(E_FATAL,L_PLUG,"cannot lock plugin lock: %s\n",strerror(err));
|
||||
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))) {
|
||||
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,9 +225,22 @@ void _plugin_writelock(void) {
|
|||
*/
|
||||
void _plugin_unlock(void) {
|
||||
int err;
|
||||
int *current_count;
|
||||
|
||||
if((err=pthread_rwlock_unlock(&_plugin_lock))) {
|
||||
DPRINTF(E_FATAL,L_PLUG,"cannot unlock plugin lock: %s\n",strerror(err));
|
||||
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))) {
|
||||
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) {
|
||||
PLUGIN_ENTRY *ppi;
|
||||
|
||||
DPRINTF(E_DBG,L_PLUG,"Entering candispatch\n");
|
||||
|
||||
_plugin_readlock();
|
||||
ppi = _plugin_list.next;
|
||||
while(ppi) {
|
||||
|
@ -279,8 +352,8 @@ int plugin_url_candispatch(WS_CONNINFO *pwsc) {
|
|||
_plugin_unlock();
|
||||
return TRUE;
|
||||
}
|
||||
ppi = ppi->next;
|
||||
}
|
||||
ppi = ppi->next;
|
||||
}
|
||||
_plugin_unlock();
|
||||
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) {
|
||||
PLUGIN_ENTRY *ppi;
|
||||
|
||||
_plugin_readlock();
|
||||
fprintf(stderr,"entering plugin_event_dispatch\n");
|
||||
|
||||
// _plugin_readlock();
|
||||
ppi = _plugin_list.next;
|
||||
while(ppi) {
|
||||
fprintf(stderr,"Checking %s\n",ppi->versionstring);
|
||||
if(ppi->type & PLUGIN_EVENT) {
|
||||
DPRINTF(E_DBG,L_PLUG,"Dispatching event %d to %s\n",
|
||||
event_id,ppi->versionstring);
|
||||
/* DPRINTF(E_DBG,L_PLUG,"Dispatching event %d to %s\n",
|
||||
event_id,ppi->versionstring); */
|
||||
|
||||
if((ppi->event_fns) && (ppi->event_fns->handler)) {
|
||||
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;
|
||||
}
|
||||
_plugin_unlock();
|
||||
// _plugin_unlock();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -48,7 +48,7 @@ void plugin_handler(int event_id, int intval, void *vp, int len) {
|
|||
|
||||
pmsg = (PLUGIN_MSG*)malloc(total_len);
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -64,7 +64,20 @@ ShowInstDetails show
|
|||
ShowUnInstDetails show
|
||||
|
||||
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}"
|
||||
Sleep 3000
|
||||
|
||||
lbl_continue:
|
||||
; should really loop until service stops...
|
||||
|
||||
!include WinMessages.nsh
|
||||
FindWindow $0 "" "Configuration"
|
||||
|
|
Loading…
Reference in New Issue