static int ts_dechunk_transform_entry(TSCont contp, TSEvent event, void *edata) { TSVIO input_vio; ts_dechunk_transform_ctx *transform_ctx = (ts_dechunk_transform_ctx*)TSContDataGet(contp); if (TSVConnClosedGet(contp)) { TSContDestroy(contp); ts_dechunk_destroy_transform_ctx(transform_ctx); return 0; } 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: default: ts_dechunk_transform_handler(contp, transform_ctx); break; } return 0; }
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 transform_bypass_event(TSCont contp, TransformData * data, TSEvent event, void *edata) { switch (event) { case TS_EVENT_VCONN_WRITE_COMPLETE: TSVConnShutdown(data->output_vc, 0, 1); break; case TS_EVENT_VCONN_WRITE_READY: default: TSVIOReenable(data->output_vio); 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; }
static int transform_read_event(TSCont contp, TransformData * data, TSEvent event, void *edata) { switch (event) { case TS_EVENT_ERROR: TSVConnAbort(data->server_vc, 1); data->server_vc = NULL; data->server_vio = NULL; TSVConnAbort(data->output_vc, 1); data->output_vc = NULL; data->output_vio = NULL; break; case TS_EVENT_VCONN_EOS: TSVConnAbort(data->server_vc, 1); data->server_vc = NULL; data->server_vio = NULL; TSVConnAbort(data->output_vc, 1); data->output_vc = NULL; data->output_vio = NULL; break; case TS_EVENT_VCONN_READ_COMPLETE: TSVConnClose(data->server_vc); data->server_vc = NULL; data->server_vio = NULL; TSVIOReenable(data->output_vio); break; case TS_EVENT_VCONN_READ_READY: TSVIOReenable(data->output_vio); break; case TS_EVENT_VCONN_WRITE_COMPLETE: TSVConnShutdown(data->output_vc, 0, 1); break; case TS_EVENT_VCONN_WRITE_READY: TSVIOReenable(data->server_vio); break; default: break; } return 0; }
static void stats_process_read(TSCont contp, TSEvent event, stats_state * my_state) { TSDebug("istats", "stats_process_read(%d)", event); if (event == TS_EVENT_VCONN_READ_READY) { my_state->output_bytes = stats_add_resp_header(my_state); TSVConnShutdown(my_state->net_vc, 1, 0); my_state->write_vio = TSVConnWrite(my_state->net_vc, contp, my_state->resp_reader, INT64_MAX); } else if (event == TS_EVENT_ERROR) { TSError("stats_process_read: Received TS_EVENT_ERROR\n"); } else if (event == TS_EVENT_VCONN_EOS) { /* client may end the connection, simply return */ return; } else if (event == TS_EVENT_NET_ACCEPT_FAILED) { TSError("stats_process_read: Received TS_EVENT_NET_ACCEPT_FAILED\n"); } else { printf("Unexpected Event %d\n", event); TSReleaseAssert(!"Unexpected Event"); } }
static int ts_lua_http_intercept_process_read(TSEvent event, ts_lua_http_intercept_ctx *ictx) { int64_t avail = TSIOBufferReaderAvail(ictx->input.reader); TSIOBufferReaderConsume(ictx->input.reader, avail); switch (event) { case TS_EVENT_VCONN_READ_READY: TSVConnShutdown(ictx->net_vc, 1, 0); case TS_EVENT_VCONN_READ_COMPLETE: case TS_EVENT_VCONN_EOS: ictx->recv_complete = 1; break; default: return -1; } return 0; }
/* Process a read event from the SM */ static void acme_process_read(TSCont contp, TSEvent event, AcmeState *my_state) { if (event == TS_EVENT_VCONN_READ_READY) { if (-1 == my_state->fd) { my_state->output_bytes = add_data_to_resp(ACME_DENIED_RESP, strlen(ACME_DENIED_RESP), my_state); } else { my_state->output_bytes = add_data_to_resp(ACME_OK_RESP, strlen(ACME_OK_RESP), my_state); } TSVConnShutdown(my_state->net_vc, 1, 0); my_state->write_vio = TSVConnWrite(my_state->net_vc, contp, my_state->resp_reader, INT64_MAX); } else if (event == TS_EVENT_ERROR) { TSError("[%s] acme_process_read: Received TS_EVENT_ERROR", PLUGIN_NAME); } else if (event == TS_EVENT_VCONN_EOS) { /* client may end the connection, simply return */ return; } else if (event == TS_EVENT_NET_ACCEPT_FAILED) { TSError("[%s] acme_process_read: Received TS_EVENT_NET_ACCEPT_FAILED", PLUGIN_NAME); } else { TSReleaseAssert(!"Unexpected Event"); } }
int ts_lua_transform_entry(TSCont contp, TSEvent ev, void *edata) { int n, event; TSVIO input_vio; ts_lua_http_transform_ctx *transform_ctx; event = (int)ev; transform_ctx = (ts_lua_http_transform_ctx *)TSContDataGet(contp); if (TSVConnClosedGet(contp)) { ts_lua_destroy_http_transform_ctx(transform_ctx); return 0; } n = 0; 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_LUA_EVENT_COROUTINE_CONT: n = (intptr_t)edata; /* FALL THROUGH */ case TS_EVENT_VCONN_WRITE_READY: default: ts_lua_transform_handler(contp, transform_ctx, event, n); break; } return 0; }
/* Process a read event from the SM */ static void hc_process_read(TSCont contp, TSEvent event, HCState *my_state) { if (event == TS_EVENT_VCONN_READ_READY) { if (my_state->data->exists) { TSDebug(PLUGIN_NAME, "Setting OK response header"); my_state->output_bytes = add_data_to_resp(my_state->info->ok, my_state->info->o_len, my_state); } else { TSDebug(PLUGIN_NAME, "Setting MISS response header"); my_state->output_bytes = add_data_to_resp(my_state->info->miss, my_state->info->m_len, my_state); } TSVConnShutdown(my_state->net_vc, 1, 0); my_state->write_vio = TSVConnWrite(my_state->net_vc, contp, my_state->resp_reader, INT64_MAX); } else if (event == TS_EVENT_ERROR) { TSError("hc_process_read: Received TS_EVENT_ERROR\n"); } else if (event == TS_EVENT_VCONN_EOS) { /* client may end the connection, simply return */ return; } else if (event == TS_EVENT_NET_ACCEPT_FAILED) { TSError("hc_process_read: Received TS_EVENT_NET_ACCEPT_FAILED\n"); } else { TSReleaseAssert(!"Unexpected Event"); } }
/** * Handle a data event from ATS. * * Handles all data events from ATS, uses process_data to handle the data * itself. * * @param[in,out] contp Pointer to the continuation * @param[in,out] event Event from ATS * @param[in,out] ibd unknown * * @returns status */ static int data_event(TSCont contp, TSEvent event, ibd_ctx *ibd) { /* Check to see if the transformation has been closed by a call to * TSVConnClose. */ tsib_txn_ctx *txndata = TSContDataGet(contp); ib_log_debug2_tx(txndata->tx, "Entering out_data for %s", ibd->ibd->dir_label); if (TSVConnClosedGet(contp)) { ib_log_debug2_tx(txndata->tx, "\tVConn is closed"); return 0; } switch (event) { case TS_EVENT_ERROR: { TSVIO input_vio; ib_log_debug2_tx(txndata->tx, "\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: ib_log_debug2_tx(txndata->tx, "\tEvent is TS_EVENT_VCONN_WRITE_COMPLETE"); /* When our output connection says that it has finished * reading all the txndata 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); if (ibd->ibd->dir == IBD_REQ) { if (!ib_flags_all(txndata->tx->flags, IB_TX_FREQ_FINISHED)) { ib_log_debug2_tx(txndata->tx, "data_event: calling ib_state_notify_request_finished()"); (*ibd->ibd->ib_notify_end)(txndata->tx->ib, txndata->tx); } } else { if (!ib_flags_all(txndata->tx->flags, IB_TX_FRES_FINISHED)) { ib_log_debug2_tx(txndata->tx, "data_event: calling ib_state_notify_response_finished()"); (*ibd->ibd->ib_notify_end)(txndata->tx->ib, txndata->tx); } } if ( (ibd->ibd->ib_notify_post != NULL) && (!ib_flags_all(txndata->tx->flags, IB_TX_FPOSTPROCESS)) ) { (*ibd->ibd->ib_notify_post)(txndata->tx->ib, txndata->tx); } if ( (ibd->ibd->ib_notify_log != NULL) && (!ib_flags_all(txndata->tx->flags, IB_TX_FLOGGING)) ) { (*ibd->ibd->ib_notify_log)(txndata->tx->ib, txndata->tx); } break; case TS_EVENT_VCONN_WRITE_READY: ib_log_debug2_tx(txndata->tx, "\tEvent is TS_EVENT_VCONN_WRITE_READY"); /* fall through */ default: ib_log_debug2_tx(txndata->tx, "\t(event is %d)", event); /* If we get a WRITE_READY event or any other type of * event (sent, perhaps, because we were re-enabled) then * we'll attempt to transform more data. */ process_data(contp, ibd); 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; }