*really* fixed the race this time
This commit is contained in:
parent
5733445333
commit
0851b29812
|
@ -1254,7 +1254,7 @@ void config_set_status(WS_CONNINFO *pwsc, int session, char *fmt, ...) {
|
||||||
newmsg = strdup(buffer);
|
newmsg = strdup(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
ws_lock_local_storage(pwsc);
|
ws_lock_local_storage(config.server);
|
||||||
if(!(pfirst = ws_get_local_storage(pwsc))) {
|
if(!(pfirst = ws_get_local_storage(pwsc))) {
|
||||||
/* new info */
|
/* new info */
|
||||||
pfirst=(SCAN_STATUS*)malloc(sizeof(SCAN_STATUS));
|
pfirst=(SCAN_STATUS*)malloc(sizeof(SCAN_STATUS));
|
||||||
|
@ -1264,21 +1264,23 @@ void config_set_status(WS_CONNINFO *pwsc, int session, char *fmt, ...) {
|
||||||
pfirst->host = strdup(pwsc->hostname);
|
pfirst->host = strdup(pwsc->hostname);
|
||||||
ws_set_local_storage(pwsc,pfirst,config_freescan);
|
ws_set_local_storage(pwsc,pfirst,config_freescan);
|
||||||
} else {
|
} else {
|
||||||
if(newmsg)
|
DPRINTF(E_FATAL,L_CONF,"Malloc Error\n");
|
||||||
free(newmsg);
|
|
||||||
ws_unlock_local_storage(pwsc);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(pfirst) {
|
||||||
/* just update */
|
/* just update */
|
||||||
if(pfirst->what) {
|
if(pfirst->what) {
|
||||||
free(pfirst->what);
|
free(pfirst->what);
|
||||||
}
|
}
|
||||||
pfirst->what=newmsg;
|
pfirst->what=newmsg;
|
||||||
pfirst->session=session;
|
pfirst->session=session;
|
||||||
|
} else {
|
||||||
|
if(newmsg)
|
||||||
|
free(newmsg);
|
||||||
|
}
|
||||||
|
|
||||||
ws_unlock_local_storage(pwsc);
|
ws_unlock_local_storage(config.server);
|
||||||
DPRINTF(E_DBG,L_CONF,"Exiting config_set_status\n");
|
DPRINTF(E_DBG,L_CONF,"Exiting config_set_status\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -175,8 +175,6 @@ int ws_unlock_unsafe(void) {
|
||||||
void ws_lock_connlist(WS_PRIVATE *pwsp) {
|
void ws_lock_connlist(WS_PRIVATE *pwsp) {
|
||||||
if(pthread_mutex_lock(&pwsp->exit_mutex))
|
if(pthread_mutex_lock(&pwsp->exit_mutex))
|
||||||
DPRINTF(E_FATAL,L_WS,"Cannot lock condition mutex\n");
|
DPRINTF(E_FATAL,L_WS,"Cannot lock condition mutex\n");
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ws_unlock_connlist(WS_PRIVATE *pwsp) {
|
void ws_unlock_connlist(WS_PRIVATE *pwsp) {
|
||||||
|
@ -263,19 +261,7 @@ void ws_remove_dispatch_thread(WS_PRIVATE *pwsp, WS_CONNINFO *pwsc) {
|
||||||
|
|
||||||
DPRINTF(E_SPAM,L_WS,"Entering ws_remove_dispatch_thread\n");
|
DPRINTF(E_SPAM,L_WS,"Entering ws_remove_dispatch_thread\n");
|
||||||
|
|
||||||
if(pthread_mutex_lock(&pwsp->exit_mutex))
|
ws_lock_connlist(pwsp);
|
||||||
DPRINTF(E_FATAL,L_WS,"Cannot lock condition mutex\n");
|
|
||||||
|
|
||||||
/* Get rid of the local storage */
|
|
||||||
if(pwsc->local_storage) {
|
|
||||||
if(pwsc->storage_callback) {
|
|
||||||
pwsc->storage_callback(pwsc->local_storage);
|
|
||||||
pwsc->local_storage=NULL;
|
|
||||||
} else {
|
|
||||||
free(pwsc->local_storage);
|
|
||||||
pwsc->local_storage=NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pTail=&(pwsp->connlist);
|
pTail=&(pwsp->connlist);
|
||||||
pHead=pwsp->connlist.next;
|
pHead=pwsp->connlist.next;
|
||||||
|
@ -298,7 +284,7 @@ void ws_remove_dispatch_thread(WS_PRIVATE *pwsp, WS_CONNINFO *pwsc) {
|
||||||
pthread_cond_signal(&pwsp->exit_cond);
|
pthread_cond_signal(&pwsp->exit_cond);
|
||||||
}
|
}
|
||||||
|
|
||||||
pthread_mutex_unlock(&pwsp->exit_mutex);
|
ws_unlock_connlist(pwsp);
|
||||||
DPRINTF(E_SPAM,L_WS,"Exiting ws_remote_dispatch_thread\n");
|
DPRINTF(E_SPAM,L_WS,"Exiting ws_remote_dispatch_thread\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -320,15 +306,14 @@ void ws_add_dispatch_thread(WS_PRIVATE *pwsp, WS_CONNINFO *pwsc) {
|
||||||
if(!pNew)
|
if(!pNew)
|
||||||
DPRINTF(E_FATAL,L_WS,"Malloc: %s\n",strerror(errno));
|
DPRINTF(E_FATAL,L_WS,"Malloc: %s\n",strerror(errno));
|
||||||
|
|
||||||
if(pthread_mutex_lock(&pwsp->exit_mutex))
|
ws_lock_connlist(pwsp);
|
||||||
DPRINTF(E_FATAL,L_WS,"Cannot lock condition mutex\n");
|
|
||||||
|
|
||||||
/* list is locked... */
|
/* list is locked... */
|
||||||
pwsp->dispatch_threads++;
|
pwsp->dispatch_threads++;
|
||||||
pNew->next = pwsp->connlist.next;
|
pNew->next = pwsp->connlist.next;
|
||||||
pwsp->connlist.next = pNew;
|
pwsp->connlist.next = pNew;
|
||||||
|
|
||||||
pthread_mutex_unlock(&pwsp->exit_mutex);
|
ws_unlock_connlist(pwsp);
|
||||||
DPRINTF(E_SPAM,L_WS,"Exiting ws_add_dispatch_thread\n");
|
DPRINTF(E_SPAM,L_WS,"Exiting ws_add_dispatch_thread\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -364,8 +349,7 @@ extern int ws_stop(WSHANDLE ws) {
|
||||||
pthread_join(pwsp->server_tid,&result);
|
pthread_join(pwsp->server_tid,&result);
|
||||||
|
|
||||||
/* Give the threads an extra push */
|
/* Give the threads an extra push */
|
||||||
if(pthread_mutex_lock(&pwsp->exit_mutex))
|
ws_lock_connlist(pwsp);
|
||||||
DPRINTF(E_FATAL,L_WS,"Cannot lock condition mutex\n");
|
|
||||||
|
|
||||||
pcl=pwsp->connlist.next;
|
pcl=pwsp->connlist.next;
|
||||||
|
|
||||||
|
@ -386,7 +370,7 @@ extern int ws_stop(WSHANDLE ws) {
|
||||||
pthread_cond_wait(&pwsp->exit_cond, &pwsp->exit_mutex);
|
pthread_cond_wait(&pwsp->exit_cond, &pwsp->exit_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
pthread_mutex_unlock(&pwsp->exit_mutex);
|
ws_unlock_connlist(pwsp);
|
||||||
|
|
||||||
free(pwsp);
|
free(pwsp);
|
||||||
|
|
||||||
|
@ -450,7 +434,7 @@ void *ws_mainthread(void *arg) {
|
||||||
ws_lock_unsafe();
|
ws_lock_unsafe();
|
||||||
pwsc->threadno=pwsp->threadno;
|
pwsc->threadno=pwsp->threadno;
|
||||||
pwsp->threadno++;
|
pwsp->threadno++;
|
||||||
ws_unlock_unsafe();
|
/* we'll hold the unsafe until the dispatch thread is registered */
|
||||||
|
|
||||||
/* now, throw off a dispatch thread */
|
/* now, throw off a dispatch thread */
|
||||||
if((err=pthread_create(&tid,NULL,ws_dispatcher,(void*)pwsc))) {
|
if((err=pthread_create(&tid,NULL,ws_dispatcher,(void*)pwsc))) {
|
||||||
|
@ -461,6 +445,7 @@ void *ws_mainthread(void *arg) {
|
||||||
ws_add_dispatch_thread(pwsp,pwsc);
|
ws_add_dispatch_thread(pwsp,pwsc);
|
||||||
pthread_detach(tid);
|
pthread_detach(tid);
|
||||||
}
|
}
|
||||||
|
ws_unlock_unsafe();
|
||||||
}
|
}
|
||||||
|
|
||||||
DPRINTF(E_SPAM,L_WS,"Exiting ws_mainthred\n");
|
DPRINTF(E_SPAM,L_WS,"Exiting ws_mainthred\n");
|
||||||
|
@ -499,11 +484,21 @@ void ws_close(WS_CONNINFO *pwsc) {
|
||||||
DPRINTF(E_DBG,L_WS,"Thread %d: Closing fd\n",pwsc->threadno);
|
DPRINTF(E_DBG,L_WS,"Thread %d: Closing fd\n",pwsc->threadno);
|
||||||
shutdown(pwsc->fd,SHUT_RDWR);
|
shutdown(pwsc->fd,SHUT_RDWR);
|
||||||
r_close(pwsc->fd);
|
r_close(pwsc->fd);
|
||||||
free(pwsc->hostname);
|
|
||||||
|
|
||||||
/* this thread is done */
|
/* this thread is done */
|
||||||
ws_remove_dispatch_thread(pwsp, pwsc);
|
ws_remove_dispatch_thread(pwsp, pwsc);
|
||||||
|
|
||||||
|
/* Get rid of the local storage */
|
||||||
|
|
||||||
|
if(pwsc->local_storage) {
|
||||||
|
if(pwsc->storage_callback) {
|
||||||
|
pwsc->storage_callback(pwsc->local_storage);
|
||||||
|
pwsc->local_storage=NULL;
|
||||||
|
pwsc->storage_callback=NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free(pwsc->hostname);
|
||||||
|
memset(pwsc,0x00,sizeof(WS_CONNINFO));
|
||||||
free(pwsc);
|
free(pwsc);
|
||||||
DPRINTF(E_SPAM,L_WS,"Exiting ws_close (thread terminating)\n");
|
DPRINTF(E_SPAM,L_WS,"Exiting ws_close (thread terminating)\n");
|
||||||
pthread_exit(NULL);
|
pthread_exit(NULL);
|
||||||
|
@ -767,6 +762,10 @@ void *ws_dispatcher(void *arg) {
|
||||||
DPRINTF(E_DBG,L_WS,"Thread %d: Entering ws_dispatcher (Connection from %s)\n",
|
DPRINTF(E_DBG,L_WS,"Thread %d: Entering ws_dispatcher (Connection from %s)\n",
|
||||||
pwsc->threadno, pwsc->hostname);
|
pwsc->threadno, pwsc->hostname);
|
||||||
|
|
||||||
|
/* quick fence to ensure that we have been registered on the thread list */
|
||||||
|
ws_lock_unsafe();
|
||||||
|
ws_unlock_unsafe();
|
||||||
|
|
||||||
while(!connection_done) {
|
while(!connection_done) {
|
||||||
/* Now, get the request from the other end
|
/* Now, get the request from the other end
|
||||||
* and decide where to dispatch it
|
* and decide where to dispatch it
|
||||||
|
@ -1006,7 +1005,7 @@ int ws_returnerror(WS_CONNINFO *pwsc,int error, char *description) {
|
||||||
/* we'll force a close here unless the user agent is
|
/* we'll force a close here unless the user agent is
|
||||||
iTunes, which seems to get pissy about it */
|
iTunes, which seems to get pissy about it */
|
||||||
useragent = ws_getarg(&pwsc->request_headers,"User-Agent");
|
useragent = ws_getarg(&pwsc->request_headers,"User-Agent");
|
||||||
if(useragent && (strncmp(useragent,"iTunes",6))) {
|
if((!useragent) || (strncmp(useragent,"iTunes",6))) {
|
||||||
pwsc->close=1;
|
pwsc->close=1;
|
||||||
ws_addarg(&pwsc->response_headers,"Connection","close");
|
ws_addarg(&pwsc->response_headers,"Connection","close");
|
||||||
}
|
}
|
||||||
|
@ -1557,10 +1556,6 @@ void ws_set_local_storage(WS_CONNINFO *pwsc, void *ptr, void (*callback)(void *)
|
||||||
|
|
||||||
if(pwsc->local_storage) {
|
if(pwsc->local_storage) {
|
||||||
DPRINTF(E_FATAL,L_WS,"ls already allocated");
|
DPRINTF(E_FATAL,L_WS,"ls already allocated");
|
||||||
if(pwsc->storage_callback) {
|
|
||||||
pwsc->storage_callback(pwsc->local_storage);
|
|
||||||
pwsc->local_storage=NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pwsc->storage_callback = callback;
|
pwsc->storage_callback = callback;
|
||||||
|
|
Loading…
Reference in New Issue