int lua_co_setkeepalive(lua_State *L) { if(!lua_isuserdata(L, 1) || !lua_isnumber(L, 2)) { lua_pushnil(L); lua_pushstring(L, "Error params!"); return 2; } cosocket_t *c*k = (cosocket_t *) lua_touserdata(L, 1); c*k->pool_size = lua_tonumber(L, 2); if(c*k->pool_size < 0) { c*k->pool_size = 0; } else if(c*k->pool_size > 4096) { c*k->pool_size = 4096; } cosocket_connection_pool_counter_t *pool_counter = get_connection_pool_counter(c*k->pool_key); if(c*k->pool_size > pool_counter->size) { pool_counter->size = c*k->pool_size; } if(lua_gettop(L) == 3 && lua_isstring(L, 3)) { size_t len = 0; const char *key = lua_tolstring(L, 3, &len); c*k->pool_key = fnv1a_32(key, len); } _lua_co_close(L, c*k); lua_pushboolean(L, 1); return 1; }
void connection_pool_counter_operate(unsigned long pool_key, int a) { /// add: connection_pool_counter_operate(key, 1); /// remove: connection_pool_counter_operate(key, -1); if(pool_key < 1) { return; } cosocket_connection_pool_counter_t *pool_counter = get_connection_pool_counter(pool_key); pool_counter->count += a; }
static int lua_co_connect(lua_State *L) { cosocket_t *c*k = NULL; { if(!lua_isuserdata(L, 1) || !lua_isstring(L, 2)) { lua_pushnil(L); lua_pushstring(L, "Error params!"); return 2; } c*k = (cosocket_t *) lua_touserdata(L, 1); if(c*k->status > 0) { lua_pushnil(L); lua_pushstring(L, "Aleady connected!"); return 2; } if(c*k->inuse == 1) { lua_pushnil(L); lua_pushstring(L, "socket busy!"); return 2; } //printf(" 0x%p connect to %s\n", L, lua_tostring(L, 2)); size_t host_len = 0; const char *host = lua_tolstring(L, 2, &host_len); if(host_len > (host[0] == '/' ? 108 : 60)) { lua_pushnil(L); lua_pushstring(L, "hostname length must be <= 60!"); return 2; } int port = 0; int pn = 3; if(host[0] != '/') { port = lua_tonumber(L, 3); if(port < 1) { lua_pushnil(L); lua_pushstring(L, "port must be > 0"); return 2; } pn = 4; } if(lua_gettop(L) >= pn) { /// set keepalive options if(lua_isnumber(L, pn)) { c*k->pool_size = lua_tonumber(L, pn); if(c*k->pool_size < 0) { c*k->pool_size = 0; } else if(c*k->pool_size > 4096) { c*k->pool_size = 4096; } pn++; } if(c*k->pool_size > 0) { size_t len = 0; if(lua_gettop(L) == pn && lua_isstring(L, pn)) { const char *key = lua_tolstring(L, pn, &len); c*k->pool_key = fnv1a_32(key, len); } } } if(c*k->pool_key == 0) { /// create a normal key int len = snprintf(temp_buf, 4096, "%s%s:%d:%ld", port > 0 ? "tcp://" : "unix://", host, port, c*k->ssl_sign); c*k->pool_key = fnv1a_32(temp_buf, len); } c*k->status = 1; c*k->L = L; c*k->read_buf = NULL; c*k->last_buf = NULL; c*k->total_buf_len = 0; c*k->buf_read_len = 0; /// check pool count cosocket_connection_pool_counter_t *pool_counter = get_connection_pool_counter(c*k->pool_key); if(pool_counter->size > c*k->pool_size) { c*k->pool_size = pool_counter->size; } if(c*k->pool_size > 0) { c*k->ptr = get_connection_in_pool(_loop_fd, c*k->pool_key, c*k); if(c*k->ptr) { ((se_ptr_t *) c*k->ptr)->data = c*k; c*k->status = 2; c*k->reusedtimes = 1; c*k->fd = ((se_ptr_t *) c*k->ptr)->fd; //printf("reuse %d\n", c*k->fd); se_be_pri(c*k->ptr, NULL); lua_pushboolean(L, 1); return 1; } if(pool_counter->count > 0 && pool_counter->count >= c*k->pool_size / _process_count) { /// pool full if((c*k->pool_wait = add_waiting_get_connection(c*k))) { c*k->status = 3; c*k->timeout_ptr = add_timeout(c*k, c*k->timeout, timeout_handle); //printf("wait %d\n", c*k->fd); c*k->inuse = 1; return lua_yield(L, 0); } else { lua_pushnil(L); lua_pushstring(L, "pool error"); return 2; } } } int fd = se_connect(_loop_fd, host, port, c*k->timeout > 0 ? c*k->timeout : 30000, be_connect, c*k); if(fd != -2) { if(fd > -1) { connection_pool_counter_operate(c*k->pool_key, 1); int ret = _be_connect(c*k, fd, 0); if(ret == -2) { return lua_yield(L, 0); } return ret; } else { lua_pushnil(L); lua_pushstring(L, strerror(errno)); return 2; } } connection_pool_counter_operate(c*k->pool_key, 1); } return lua_yield(L, 0); }