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) {
|
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);
|
||||||
|
|
100
src/plugin.c
100
src/plugin.c
|
@ -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,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) {
|
void _plugin_readlock(void) {
|
||||||
int err;
|
int err;
|
||||||
|
int *current_count;
|
||||||
|
|
||||||
if((err=pthread_rwlock_rdlock(&_plugin_lock))) {
|
current_count = pthread_getspecific(_plugin_lock_key);
|
||||||
DPRINTF(E_FATAL,L_PLUG,"cannot lock plugin lock: %s\n",strerror(err));
|
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) {
|
void _plugin_writelock(void) {
|
||||||
int err;
|
int err;
|
||||||
|
int *current_count;
|
||||||
|
|
||||||
if((err=pthread_rwlock_wrlock(&_plugin_lock))) {
|
current_count = pthread_getspecific(_plugin_lock_key);
|
||||||
DPRINTF(E_FATAL,L_PLUG,"cannot lock plugin lock: %s\n",strerror(err));
|
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) {
|
void _plugin_unlock(void) {
|
||||||
int err;
|
int err;
|
||||||
|
int *current_count;
|
||||||
|
|
||||||
if((err=pthread_rwlock_unlock(&_plugin_lock))) {
|
current_count = pthread_getspecific(_plugin_lock_key);
|
||||||
DPRINTF(E_FATAL,L_PLUG,"cannot unlock plugin lock: %s\n",strerror(err));
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -269,6 +340,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;
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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"
|
||||||
|
|
Loading…
Reference in New Issue