fix deadlock on smp (fingers crossed)

This commit is contained in:
Ron Pedde 2006-06-28 05:29:41 +00:00
parent 067d252f81
commit 02664912f6

View File

@ -151,99 +151,6 @@ int plugin_deinit(void) {
return TRUE; return TRUE;
} }
/**
* 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;
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_SPAM,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);
}
}
/**
* lock the plugin_mutex
*/
void _plugin_writelock(void) {
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_SPAM,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);
}
}
/**
* unlock the plugin_mutex
*/
void _plugin_unlock(void) {
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))) {
DPRINTF(E_FATAL,L_PLUG,"cannot unlock plugin lock: %s\n",strerror(err));
}
} else {
pthread_setspecific(_plugin_lock_key,(void*)current_count);
}
}
/** /**
* return the error * return the error
* *
@ -276,8 +183,6 @@ void _plugin_recalc_codecs(void) {
PLUGIN_ENTRY *ppi; PLUGIN_ENTRY *ppi;
size_t size=0; size_t size=0;
_plugin_writelock();
ppi = _plugin_list.next; ppi = _plugin_list.next;
while(ppi) { while(ppi) {
if(ppi->pinfo->type & PLUGIN_TRANSCODE) { if(ppi->pinfo->type & PLUGIN_TRANSCODE) {
@ -310,7 +215,6 @@ void _plugin_recalc_codecs(void) {
} }
DPRINTF(E_DBG,L_PLUG,"New transcode codec list: %s\n",_plugin_ssc_codecs); DPRINTF(E_DBG,L_PLUG,"New transcode codec list: %s\n",_plugin_ssc_codecs);
_plugin_unlock();
return; return;
} }
@ -369,8 +273,6 @@ int plugin_load(char **pe, char *path) {
DPRINTF(E_INF,L_PLUG,"Loaded plugin %s (%s)\n",path,pinfo->server); DPRINTF(E_INF,L_PLUG,"Loaded plugin %s (%s)\n",path,pinfo->server);
_plugin_writelock();
if(!_plugin_initialized) { if(!_plugin_initialized) {
_plugin_initialized = 1; _plugin_initialized = 1;
memset((void*)&_plugin_list,0,sizeof(_plugin_list)); memset((void*)&_plugin_list,0,sizeof(_plugin_list));
@ -379,8 +281,6 @@ int plugin_load(char **pe, char *path) {
ppi->next = _plugin_list.next; ppi->next = _plugin_list.next;
_plugin_list.next = ppi; _plugin_list.next = ppi;
_plugin_unlock();
_plugin_recalc_codecs(); _plugin_recalc_codecs();
return PLUGIN_E_SUCCESS; return PLUGIN_E_SUCCESS;
} }
@ -396,19 +296,16 @@ int plugin_url_candispatch(WS_CONNINFO *pwsc) {
DPRINTF(E_DBG,L_PLUG,"Entering candispatch\n"); DPRINTF(E_DBG,L_PLUG,"Entering candispatch\n");
_plugin_readlock();
ppi = _plugin_list.next; ppi = _plugin_list.next;
while(ppi) { while(ppi) {
if(ppi->pinfo->type & PLUGIN_OUTPUT) { if(ppi->pinfo->type & PLUGIN_OUTPUT) {
if(!regexec(&ppi->regex,pwsc->uri,0,NULL,0)) { if(!regexec(&ppi->regex,pwsc->uri,0,NULL,0)) {
/* we have a winner */ /* we have a winner */
_plugin_unlock();
return TRUE; return TRUE;
} }
} }
ppi = ppi->next; ppi = ppi->next;
} }
_plugin_unlock();
return FALSE; return FALSE;
} }
@ -423,7 +320,6 @@ void plugin_url_handle(WS_CONNINFO *pwsc) {
PLUGIN_ENTRY *ppi; PLUGIN_ENTRY *ppi;
void (*disp_fn)(WS_CONNINFO *pwsc); void (*disp_fn)(WS_CONNINFO *pwsc);
_plugin_readlock();
ppi = _plugin_list.next; ppi = _plugin_list.next;
while(ppi) { while(ppi) {
if(ppi->pinfo->type & PLUGIN_OUTPUT) { if(ppi->pinfo->type & PLUGIN_OUTPUT) {
@ -435,7 +331,6 @@ void plugin_url_handle(WS_CONNINFO *pwsc) {
/* so functions must be a tag_plugin_output_fn */ /* so functions must be a tag_plugin_output_fn */
disp_fn=(ppi->pinfo->output_fns)->handler; disp_fn=(ppi->pinfo->output_fns)->handler;
disp_fn(pwsc); disp_fn(pwsc);
_plugin_unlock();
return; return;
} }
} }
@ -444,7 +339,6 @@ void plugin_url_handle(WS_CONNINFO *pwsc) {
/* should 500 here or something */ /* should 500 here or something */
ws_returnerror(pwsc, 500, "Can't find plugin handler"); ws_returnerror(pwsc, 500, "Can't find plugin handler");
_plugin_unlock();
return; return;
} }
@ -461,7 +355,6 @@ int plugin_rend_register(char *name, int port, char *iface, char *txt) {
int name_len; int name_len;
_plugin_readlock();
ppi = _plugin_list.next; ppi = _plugin_list.next;
while(ppi) { while(ppi) {
@ -501,8 +394,6 @@ int plugin_rend_register(char *name, int port, char *iface, char *txt) {
ppi=ppi->next; ppi=ppi->next;
} }
_plugin_unlock();
return TRUE; return TRUE;
} }
@ -519,7 +410,6 @@ int plugin_auth_handle(WS_CONNINFO *pwsc, char *username, char *pw) {
int (*auth_fn)(WS_CONNINFO *pwsc, char *username, char *pw); int (*auth_fn)(WS_CONNINFO *pwsc, char *username, char *pw);
int result; int result;
_plugin_readlock();
ppi = _plugin_list.next; ppi = _plugin_list.next;
while(ppi) { while(ppi) {
if(ppi->pinfo->type & PLUGIN_OUTPUT) { if(ppi->pinfo->type & PLUGIN_OUTPUT) {
@ -532,10 +422,8 @@ int plugin_auth_handle(WS_CONNINFO *pwsc, char *username, char *pw) {
auth_fn=(ppi->pinfo->output_fns)->auth; auth_fn=(ppi->pinfo->output_fns)->auth;
if(auth_fn) { if(auth_fn) {
result=auth_fn(pwsc,username,pw); result=auth_fn(pwsc,username,pw);
_plugin_unlock();
return result; return result;
} else { } else {
_plugin_unlock();
return TRUE; return TRUE;
} }
} }
@ -545,7 +433,6 @@ int plugin_auth_handle(WS_CONNINFO *pwsc, char *username, char *pw) {
/* should 500 here or something */ /* should 500 here or something */
ws_returnerror(pwsc, 500, "Can't find plugin handler"); ws_returnerror(pwsc, 500, "Can't find plugin handler");
_plugin_unlock();
return FALSE; return FALSE;
} }
@ -555,8 +442,6 @@ 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;
/* FIXME: Something is wrong is readlock deadlocks... */
// _plugin_readlock();
ppi = _plugin_list.next; ppi = _plugin_list.next;
while(ppi) { while(ppi) {
if(ppi->pinfo->type & PLUGIN_EVENT) { if(ppi->pinfo->type & PLUGIN_EVENT) {
@ -569,7 +454,6 @@ void plugin_event_dispatch(int event_id, int intval, void *vp, int len) {
} }
ppi=ppi->next; ppi=ppi->next;
} }
// _plugin_unlock();
} }
/** /**
@ -609,12 +493,10 @@ int plugin_ssc_should_transcode(WS_CONNINFO *pwsc, char *codec) {
if(strstr(native_codecs,codec)) if(strstr(native_codecs,codec))
return FALSE; return FALSE;
_plugin_readlock();
result = FALSE; result = FALSE;
if(strstr(_plugin_ssc_codecs,codec)) { if(strstr(_plugin_ssc_codecs,codec)) {
result = TRUE; result = TRUE;
} }
_plugin_unlock();
return result; return result;
} }
@ -674,7 +556,6 @@ int plugin_ssc_transcode(WS_CONNINFO *pwsc, char *file, char *codec, int duratio
/* first, find the plugin that will do the conversion */ /* first, find the plugin that will do the conversion */
_plugin_readlock();
ppi = _plugin_list.next; ppi = _plugin_list.next;
while((ppi) && (!pfn)) { while((ppi) && (!pfn)) {
@ -729,7 +610,6 @@ int plugin_ssc_transcode(WS_CONNINFO *pwsc, char *file, char *codec, int duratio
ws_returnerror(pwsc,500,"Internal error"); ws_returnerror(pwsc,500,"Internal error");
} }
_plugin_unlock();
return result; return result;
} }