mirror of
https://github.com/3proxy/3proxy.git
synced 2026-10-15 16:15:49 +08:00
FIx: race condition on service reload
This commit is contained in:
parent
5e71f7daff
commit
a0ea1b3e7d
@ -1333,7 +1333,16 @@ void srvfree(struct srvparam * srv){
|
||||
if(srv->cbsock != INVALID_SOCKET) so._closesocket(srv->so.state, srv->cbsock);
|
||||
srv->cbsock = INVALID_SOCKET;
|
||||
srv->service = S_ZOMBIE;
|
||||
while(srv->child) usleep(SLEEPTIME * 100);
|
||||
/* under the mutex, so the last child has let go of it before it is destroyed */
|
||||
for(;;){
|
||||
struct clientparam *child;
|
||||
|
||||
_3proxy_mutex_lock(&srv->counter_mutex);
|
||||
child = srv->child;
|
||||
_3proxy_mutex_unlock(&srv->counter_mutex);
|
||||
if(!child) break;
|
||||
usleep(SLEEPTIME * 100);
|
||||
}
|
||||
#ifndef STDMAIN
|
||||
if(srv->filter){
|
||||
while(srv->nfilters){
|
||||
@ -1378,22 +1387,13 @@ void srvfree(struct srvparam * srv){
|
||||
void freeparam(struct clientparam * param) {
|
||||
if(param->srv){
|
||||
if(param->srv->so.freefunc) param->srv->so.freefunc(param->sostate);
|
||||
_3proxy_mutex_lock(¶m->srv->counter_mutex);
|
||||
#ifndef STDMAIN
|
||||
if(param->srv->service == S_UDPPM) hashdelete(&udp_table, param);
|
||||
#endif
|
||||
if(param->prev || param->next || param->srv->child == param){
|
||||
if(param->prev){
|
||||
param->prev->next = param->next;
|
||||
}
|
||||
else
|
||||
param->srv->child = param->next;
|
||||
if(param->next){
|
||||
param->next->prev = param->prev;
|
||||
}
|
||||
(param->srv->childcount)--;
|
||||
if(param->srv->service == S_UDPPM){
|
||||
_3proxy_mutex_lock(¶m->srv->counter_mutex);
|
||||
hashdelete(&udp_table, param);
|
||||
_3proxy_mutex_unlock(¶m->srv->counter_mutex);
|
||||
}
|
||||
_3proxy_mutex_unlock(¶m->srv->counter_mutex);
|
||||
#endif
|
||||
}
|
||||
if(param->clibuf) free(param->clibuf);
|
||||
if(param->srvbuf) free(param->srvbuf);
|
||||
@ -1433,6 +1433,24 @@ void freeparam(struct clientparam * param) {
|
||||
}
|
||||
if(param->connlim) stopconnlims(param);
|
||||
#endif
|
||||
/* Leaving the service comes last. Once its last child is gone, srvfree()
|
||||
frees the service along with its socket functions, filters and mutex,
|
||||
and a close above may have lingered for seconds before getting here. */
|
||||
if(param->srv){
|
||||
_3proxy_mutex_lock(¶m->srv->counter_mutex);
|
||||
if(param->prev || param->next || param->srv->child == param){
|
||||
if(param->prev){
|
||||
param->prev->next = param->next;
|
||||
}
|
||||
else
|
||||
param->srv->child = param->next;
|
||||
if(param->next){
|
||||
param->next->prev = param->prev;
|
||||
}
|
||||
(param->srv->childcount)--;
|
||||
}
|
||||
_3proxy_mutex_unlock(¶m->srv->counter_mutex);
|
||||
}
|
||||
if(param->hostname) free(param->hostname);
|
||||
if(param->username) free(param->username);
|
||||
if(param->password) free(param->password);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user