/* When the handle is called, the net_vc is returned. */ static int accept_handler(TSCont contp, TSEvent event, void *edata) { TSCont txn_sm; TSMutex pmutex; switch (event) { case TS_EVENT_NET_ACCEPT: /* Create a new mutex for the TxnSM, which is going to handle the incoming request. */ pmutex = (TSMutex)TSMutexCreate(); txn_sm = (TSCont)TxnSMCreate(pmutex, (TSVConn)edata, server_port); /* This is no reason for not grabbing the lock. So skip the routine which handle LockTry failure case. */ TSMutexLockTry(pmutex); // TODO: why should it not check if we got the lock?? TSContCall(txn_sm, 0, NULL); TSMutexUnlock(pmutex); break; default: /* Something wrong with the network, if there are any pending NetAccept, cancel them. */ if (pending_action && !TSActionDone(pending_action)) TSActionCancel(pending_action); TSContDestroy(contp); break; } return TS_EVENT_NONE; }
static int transform_connect(TSCont contp, TransformData *data) { TSAction action; int content_length; struct sockaddr_in ip_addr; data->state = STATE_CONNECT; content_length = TSIOBufferReaderAvail(data->input_reader); if (content_length >= 0) { data->content_length = content_length; data->content_length = htonl(data->content_length); /* Prepend the content length to the buffer. * If we decide to not send the content to the transforming * server then we need to make sure and skip input_reader * over the content length. */ { TSIOBuffer temp; TSIOBufferReader tempReader; temp = TSIOBufferCreate(); tempReader = TSIOBufferReaderAlloc(temp); TSIOBufferWrite(temp, (const char *)&content_length, sizeof(int)); TSIOBufferCopy(temp, data->input_reader, content_length, 0); TSIOBufferReaderFree(data->input_reader); TSIOBufferDestroy(data->input_buf); data->input_buf = temp; data->input_reader = tempReader; } } else { TSError("[%s] TSIOBufferReaderAvail returns TS_ERROR", PLUGIN_NAME); return 0; } /* TODO: This only supports IPv4, probably should be changed at some point, but it's an example ... */ memset(&ip_addr, 0, sizeof(ip_addr)); ip_addr.sin_family = AF_INET; ip_addr.sin_addr.s_addr = server_ip; /* Should be in network byte order */ ip_addr.sin_port = server_port; TSDebug(PLUGIN_NAME, "net connect."); action = TSNetConnect(contp, (struct sockaddr const *)&ip_addr); if (!TSActionDone(action)) { data->pending_action = action; } return 0; }
static int ts_lua_cache_remove(lua_State *L) { const char *keystr, *optstr; size_t key_len, opt_len; int n; TSCont contp; TSCacheKey key; TSAction action; ts_lua_cont_info *ci; ts_lua_async_item *ai; ts_lua_cache_info *info; ci = ts_lua_get_cont_info(L); if (ci == NULL) return 0; n = lua_gettop(L); if (n < 1) { return luaL_error(L, "'ts.cache_remove' requires parameter"); } /* keystr */ if (!lua_isstring(L, 1)) { return luaL_error(L, "'ts.cache_remove' first param is not string"); } keystr = luaL_checklstring(L, 1, &key_len); optstr = NULL; opt_len = 0; /* option */ if (n >= 2 && lua_isstring(L, 2)) { optstr = luaL_checklstring(L, 2, &opt_len);; } key = ts_lua_cache_key_create(keystr, key_len, optstr, opt_len); if (key == NULL) { return luaL_error(L, "'ts.cache_remove' failed"); } info = (ts_lua_cache_info*)TSmalloc(sizeof(ts_lua_cache_info)); memset(info, 0, sizeof(ts_lua_cache_info)); info->cache_key = key; contp = TSContCreate(ts_lua_cache_remove_handler, ci->mutex); ai = ts_lua_async_create_item(contp, ts_lua_cache_cleanup, info, ci); TSContDataSet(contp, ai); action = TSCacheRemove(contp, key); if (!TSActionDone(action)) { info->cache_action = action; return lua_yield(L, 0); } else { // action done ts_lua_release_cache_info(info, 1); ai->data = NULL; return 0; } }
static int ts_lua_cache_open(lua_State *L) { const char *keystr, *optstr; size_t key_len, opt_len; int operate, n; TSCont contp; TSCacheKey key; TSAction action; ts_lua_cont_info *ci; ts_lua_async_item *ai; ts_lua_cache_info *info; ci = ts_lua_get_cont_info(L); if (ci == NULL) return 0; n = lua_gettop(L); if (n < 2) { return luaL_error(L, "'ts.cache_open' requires parameter"); } /* keystr */ if (!lua_isstring(L, 1)) { return luaL_error(L, "'ts.cache_open' first param is not string"); } else if (!lua_isnumber(L, 2)) { return luaL_error(L, "'ts.cache_open' second param is not TS_LUA_CACHE_READ/TS_LUA_CACHE_WRITE"); } keystr = luaL_checklstring(L, 1, &key_len); operate = lua_tonumber(L, 2); if (operate != TS_LUA_CACHE_READ && operate != TS_LUA_CACHE_WRITE) { return luaL_error(L, "'ts.cache_open' second param is not TS_LUA_CACHE_READ/TS_LUA_CACHE_WRITE"); } optstr = NULL; opt_len = 0; /* option */ if (n >= 3 && lua_isstring(L, 3)) { optstr = luaL_checklstring(L, 3, &opt_len); } key = ts_lua_cache_key_create(keystr, key_len, optstr, opt_len); if (key == NULL) { return luaL_error(L, "'ts.cache_open' failed"); } info = (ts_lua_cache_info*)TSmalloc(sizeof(ts_lua_cache_info)); memset(info, 0, sizeof(ts_lua_cache_info)); info->cache_key = key; info->optype = operate; contp = TSContCreate(ts_lua_cache_main_handler, ci->mutex); ai = ts_lua_async_create_item(contp, ts_lua_cache_cleanup, info, ci); TSContDataSet(contp, ai); info->contp = contp; info->ioh.buffer = TSIOBufferCreate(); info->ioh.reader = TSIOBufferReaderAlloc(info->ioh.buffer); if (operate == TS_LUA_CACHE_READ) { info->reserved.buffer = TSIOBufferCreate(); info->reserved.reader = TSIOBufferReaderAlloc(info->reserved.buffer); info->current_handler = &ts_lua_cache_open_read; action = TSCacheRead(contp, key); } else { info->current_handler = &ts_lua_cache_open_write; action = TSCacheWrite(contp, key); } if (TSActionDone(action)) { // done return 1; } else { // undone info->cache_action = action; return lua_yield(L, 0); } }