/* * 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; }
static void q_destroy(Queue *q) { assert(q); MT_lock_destroy(&q->l); MT_sema_destroy(&q->s); GDKfree(q->data); GDKfree(q); }
/* * 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; }