/* * When a client needs to be terminated then the file descriptors for * its input/output are simply closed. This leads to a graceful * degradation, but may take some time when the client is busy. A more * forcefull method is to kill the client thread, but this may leave * locks and semaphores in an undesirable state. * * The routine freeClient ends a single client session, but through side * effects of sharing IO descriptors, also its children. Conversely, a * child can not close a parent. */ void MCfreeClient(Client c) { c->mode = FINISHCLIENT; #ifdef MAL_CLIENT_DEBUG fprintf(stderr,"# Free client %d\n", c->idx); #endif MCexitClient(c); /* scope list and curprg can not be removed, because the client may * reside in a quit() command. Therefore the scopelist is re-used. */ c->scenario = NULL; if (c->prompt) GDKfree(c->prompt); c->prompt = NULL; c->promptlength = -1; if (c->errbuf) { /* no client threads in embedded mode */ #ifndef HAVE_EMBEDDED GDKsetbuf(0); #endif if (c->father == NULL) GDKfree(c->errbuf); c->errbuf = 0; } if (c->usermodule) freeModule(c->usermodule); c->usermodule = c->curmodule = 0; c->father = 0; c->login = c->lastcmd = 0; //c->active = 0; c->qtimeout = 0; c->stimeout = 0; c->user = oid_nil; if( c->username){ GDKfree(c->username); c->username = 0; } c->mythread = 0; if (c->glb) { freeStack(c->glb); c->glb = NULL; } if( c->error_row){ BBPrelease(c->error_row->batCacheid); BBPrelease(c->error_fld->batCacheid); BBPrelease(c->error_msg->batCacheid); BBPrelease(c->error_input->batCacheid); c->error_row = c->error_fld = c->error_msg = c->error_input = NULL; } if( c->wlc) freeMalBlk(c->wlc); c->wlc_kind = 0; c->wlc = NULL; MT_sema_destroy(&c->s); c->mode = MCshutdowninprogress()? BLOCKCLIENT: FREECLIENT; }
/* * At the end of the server session all remaining structured are * explicitly released to simplify detection of memory leakage problems. */ void MCcleanupClients(void) { Client c; for (c = mal_clients; c < mal_clients + MAL_MAXCLIENTS; c++) { if (c->prompt) { GDKfree(c->prompt); c->prompt = NULL; } c->user = oid_nil; assert(c->bak == NULL); MCexitClient(c); } }
/* * When a client needs to be terminated then the file descriptors for * its input/output are simply closed. This leads to a graceful * degradation, but may take some time when the client is busy. A more * forcefull method is to kill the client thread, but this may leave * locks and semaphores in an undesirable state. * * The routine freeClient ends a single client session, but through side * effects of sharing IO descriptors, also its children. Conversely, a * child can not close a parent. */ void freeClient(Client c) { Thread t = c->mythread; c->mode = FINISHCLIENT; #ifdef MAL_CLIENT_DEBUG printf("# Free client %d\n", c->idx); #endif MCexitClient(c); /* scope list and curprg can not be removed, because the client may * reside in a quit() command. Therefore the scopelist is re-used. */ c->scenario = NULL; if (c->prompt) GDKfree(c->prompt); c->prompt = NULL; c->promptlength = -1; if (c->errbuf) { GDKsetbuf(0); if (c->father == NULL) GDKfree(c->errbuf); c->errbuf = 0; } c->father = 0; c->login = c->lastcmd = 0; //c->active = 0; c->qtimeout = 0; c->stimeout = 0; c->user = oid_nil; if( c->username){ GDKfree(c->username); c->username = 0; } c->mythread = 0; GDKfree(c->glb); c->glb = NULL; if( c->error_row){ BBPdecref(c->error_row->batCacheid,TRUE); BBPdecref(c->error_fld->batCacheid,TRUE); BBPdecref(c->error_msg->batCacheid,TRUE); BBPdecref(c->error_input->batCacheid,TRUE); c->error_row = c->error_fld = c->error_msg = c->error_input = NULL; } if (t) THRdel(t); /* you may perform suicide */ MT_sema_destroy(&c->s); c->mode = MCshutdowninprogress()? BLOCKCLIENT: FREECLIENT; }
/* * When a client needs to be terminated then the file descriptors for * its input/output are simply closed. This leads to a graceful * degradation, but may take some time when the client is busy. A more * forcefull method is to kill the client thread, but this may leave * locks and semaphores in an undesirable state. * * The routine freeClient ends a single client session, but through side * effects of sharing IO descriptors, also its children. Conversely, a * child can not close a parent. */ void freeClient(Client c) { Thread t = c->mythread; c->mode = FINISHING; #ifdef MAL_CLIENT_DEBUG printf("# Free client %d\n", c->idx); #endif MCexitClient(c); /* scope list and curprg can not be removed, because the client may * reside in a quit() command. Therefore the scopelist is re-used. */ c->scenario = NULL; if (c->prompt) GDKfree(c->prompt); c->prompt = NULL; c->promptlength = -1; if (c->errbuf) { GDKsetbuf(0); if (c->father == NULL) GDKfree(c->errbuf); c->errbuf = 0; } c->father = 0; c->login = c->lastcmd = 0; c->qtimeout = 0; c->stimeout = 0; if (c->rcc) { GDKfree(c->rcc); c->rcc = NULL; } c->user = oid_nil; c->mythread = 0; c->mode = FREECLIENT; GDKfree(c->glb); c->glb = NULL; if (t) THRdel(t); /* you may perform suicide */ }