static int null_transform(TSCont contp, TSEvent event, void *edata) { /* Check to see if the transformation has been closed by a call to * TSVConnClose. */ TSDebug("null-transform", "Entering null_transform()"); if (TSVConnClosedGet(contp)) { TSDebug("null-transform", "\tVConn is closed"); my_data_destroy(TSContDataGet(contp)); TSContDestroy(contp); return 0; } else { switch (event) { case TS_EVENT_ERROR: { TSVIO input_vio; TSDebug("null-transform", "\tEvent is TS_EVENT_ERROR"); /* Get the write VIO for the write operation that was * performed on ourself. This VIO contains the continuation of * our parent transformation. This is the input VIO. */ input_vio = TSVConnWriteVIOGet(contp); /* Call back the write VIO continuation to let it know that we * have completed the write operation. */ TSContCall(TSVIOContGet(input_vio), TS_EVENT_ERROR, input_vio); } break; case TS_EVENT_VCONN_WRITE_COMPLETE: TSDebug("null-transform", "\tEvent is TS_EVENT_VCONN_WRITE_COMPLETE"); /* When our output connection says that it has finished * reading all the data we've written to it then we should * shutdown the write portion of its connection to * indicate that we don't want to hear about it anymore. */ TSVConnShutdown(TSTransformOutputVConnGet(contp), 0, 1); break; case TS_EVENT_VCONN_WRITE_READY: TSDebug("null-transform", "\tEvent is TS_EVENT_VCONN_WRITE_READY"); default: TSDebug("null-transform", "\t(event is %d)", event); /* If we get a WRITE_READY event or any other type of * event (sent, perhaps, because we were reenabled) then * we'll attempt to transform more data. */ handle_transform(contp); break; } } return 0; }
static int bnull_transform(TSCont contp, TSEvent event, void *edata) { /* Check to see if the transformation has been closed by a call to TSVConnClose. */ if (TSVConnClosedGet(contp)) { my_data_destroy(TSContDataGet(contp)); TSContDestroy(contp); } else { switch (event) { case TS_EVENT_ERROR:{ TSVIO write_vio; /* Get the write VIO for the write operation that was performed on ourself. This VIO contains the continuation of our parent transformation. */ write_vio = TSVConnWriteVIOGet(contp); /* Call back the write VIO continuation to let it know that we have completed the write operation. */ TSContCall(TSVIOContGet(write_vio), TS_EVENT_ERROR, write_vio); break; } case TS_EVENT_VCONN_WRITE_COMPLETE: /* When our output connection says that it has finished reading all the data we've written to it then we should shutdown the write portion of its connection to indicate that we don't want to hear about it anymore. */ TSVConnShutdown(TSTransformOutputVConnGet(contp), 0, 1); break; case TS_EVENT_VCONN_WRITE_READY: default: /* If we get a WRITE_READY event or any other type of event (sent, perhaps, because we were reenabled) then we'll attempt to transform more data. */ handle_transform(contp); break; } } return 0; }
/*------------------------------------------------------------------------- transform_handler Handler for all events received during the transformation process Input: contp continuation for the current transaction event event received data pointer on optional data Output : Return Value: -------------------------------------------------------------------------*/ static int transform_handler(TSCont contp, TSEvent event, void *edata) { TSVIO input_vio; ContData *data; int state, retval; /* This section will be called by both TS internal and the thread. Protect it with a mutex to avoid concurrent calls. */ /* Handle TryLock result */ if (TSMutexLockTry(TSContMutexGet(contp)) != TS_SUCCESS) { TSCont c = TSContCreate(trylock_handler, NULL); TryLockData *d = TSmalloc(sizeof(TryLockData)); d->contp = contp; d->event = event; TSContDataSet(c, d); TSContSchedule(c, 10, TS_THREAD_POOL_DEFAULT); return 1; } data = TSContDataGet(contp); TSAssert(data->magic == MAGIC_ALIVE); state = data->state; /* Check to see if the transformation has been closed */ retval = TSVConnClosedGet(contp); if (retval) { /* If the thread is still executing its job, we don't want to destroy the continuation right away as the thread will call us back on this continuation. */ if (state == STATE_READ_PSI) { TSContSchedule(contp, 10, TS_THREAD_POOL_DEFAULT); } else { TSMutexUnlock(TSContMutexGet(contp)); cont_data_destroy(TSContDataGet(contp)); TSContDestroy(contp); return 1; } } else { switch (event) { case TS_EVENT_ERROR: input_vio = TSVConnWriteVIOGet(contp); TSContCall(TSVIOContGet(input_vio), TS_EVENT_ERROR, input_vio); break; case TS_EVENT_VCONN_WRITE_COMPLETE: TSVConnShutdown(TSTransformOutputVConnGet(contp), 0, 1); break; case TS_EVENT_VCONN_WRITE_READY: /* downstream vconnection is done reading data we've write into it. let's read some more data from upstream if we're in read state. */ if (state == STATE_READ_DATA) { handle_transform(contp); } break; case TS_EVENT_IMMEDIATE: if (state == STATE_READ_DATA) { /* upstream vconnection signals some more data ready to be read let's try to transform some more data */ handle_transform(contp); } else if (state == STATE_DUMP_PSI) { /* The thread scheduled an event on our continuation to let us know it has completed its job Let's dump the include content to the output vconnection */ dump_psi(contp); wake_up_streams(contp); } break; default: TSAssert(!"Unexpected event"); break; } } TSMutexUnlock(TSContMutexGet(contp)); return 1; }