Ejemplo n.º 1
0
void http_hdr_req_free(HTTP_HDR_REQ *hh)
{
	ACL_ARRAY *pool;

	if (hh == NULL)
		return;

	if (var_http_tls_cache <= 0 || cache_pool == NULL) {
		__hdr_free_member(hh);
		http_hdr_free((HTTP_HDR *) hh);
		return;
	}

#ifdef	USE_TLS_EX
	pool = (ACL_ARRAY*) acl_pthread_tls_get(&cache_key);
	if (pool != NULL) {
		pool->push_back(pool, hh);
		return;
	}
#else
	pool = (ACL_ARRAY*) acl_pthread_getspecific(cache_key);
	if (pool != NULL && acl_array_size(pool) < var_http_tls_cache) {
		pool->push_back(pool, hh);
		return;
	}
#endif
	__hdr_free_member(hh);
	http_hdr_free((HTTP_HDR *) hh);
}
Ejemplo n.º 2
0
int acl_mem_slice_gc(void)
{
	ACL_MEM_SLICE *mem_slice = acl_pthread_getspecific(__mem_slice_key);

	if (!mem_slice)
		return -1;
	return mem_slice_gc(mem_slice);
}
Ejemplo n.º 3
0
int acl_read_wait(ACL_SOCKET fd, int timeout)
{
	const char *myname = "acl_read_wait";
	int op = EPOLL_CTL_ADD, delay = timeout * 1000, *epoll_fd;
	struct epoll_event ee, events[1];

	acl_assert(acl_pthread_once(&epoll_once, thread_epoll_init) == 0);
	epoll_fd = (int*) acl_pthread_getspecific(epoll_key);
	if (epoll_fd == NULL) {
		epoll_fd = (int*) acl_mymalloc(sizeof(int));
		acl_assert(acl_pthread_setspecific(epoll_key, epoll_fd) == 0);
		if ((unsigned long) acl_pthread_self()
			== acl_main_thread_self())
		{
			main_epoll_read_fd = epoll_fd;
			atexit(main_epoll_end);
		}

		*epoll_fd = epoll_create(1);
	}

	ee.events = EPOLLIN | EPOLLHUP | EPOLLERR;
	ee.data.u64 = 0;
	ee.data.fd = fd;
	if (epoll_ctl(*epoll_fd, op, fd, &ee) == -1) {
		acl_msg_error("%s(%d): epoll_ctl error: %s, fd: %d",
			myname, __LINE__, acl_last_serror(), fd);
		return -1;
	}

	if (epoll_wait(*epoll_fd, events, 1, delay) == -1) {
		acl_msg_error("%s(%d): epoll_wait error: %s, fd: %d",
			myname, __LINE__, acl_last_serror(), fd);
		return -1;
	}

	if ((events[0].events & (EPOLLERR | EPOLLHUP)) != 0)
		return -1;

	if ((events[0].events & EPOLLIN) == 0) {
		acl_set_error(ACL_ETIMEDOUT);
		return -1;
	}

	ee.events = 0;
	ee.data.u64 = 0;
	ee.data.fd = fd;
	if (epoll_ctl(*epoll_fd, EPOLL_CTL_DEL, fd, &ee) == -1) {
		acl_msg_error("%s(%d): epoll_ctl error: %s, fd: %d",
			myname, __LINE__, acl_last_serror(), fd);
		return -1;
	}

	return 0;
}
Ejemplo n.º 4
0
void acl_mem_slice_destroy(void)
{
	ACL_MEM_SLICE *mem_slice = acl_pthread_getspecific(__mem_slice_key);

	if (mem_slice == NULL)
		return;
	/* 释放该线程所拥有的内存切片池对象 */
	mem_slice_free(mem_slice);
	acl_pthread_setspecific(__mem_slice_key, NULL);
	if ((unsigned long) acl_pthread_self() == acl_main_thread_self())
		__main_mem_slice = NULL;
}
Ejemplo n.º 5
0
	virtual void* run()
	{
		// 回写需要先设置远程连接地址
		acl::socket_stream* conn = (acl::socket_stream*)
			acl_pthread_getspecific(stream_key);
		acl_assert(conn);
		conn->set_peer(peer_addr_);
		conn->write(buf_, len_);

		// 因为该对象是动态分配的,所以需要释放掉
		delete this;
		return NULL;
	}
Ejemplo n.º 6
0
static void *tls_calloc(size_t len)
{
	void *ptr;

	(void) acl_pthread_once(&once_control, once_init);
	ptr = (void*) acl_pthread_getspecific(once_key);
	if (ptr == NULL) {
		ptr = acl_mycalloc(1, len);
		acl_pthread_setspecific(once_key, ptr);
		if ((unsigned long) acl_pthread_self() == acl_main_thread_self())
			__tls = ptr;
	}
	return ptr;
}
Ejemplo n.º 7
0
HTTP_HDR_REQ *http_hdr_req_new(void)
{
	HTTP_HDR_REQ *hh;
	ACL_ARRAY *pool;

	if (var_http_tls_cache <= 0) {
		hh = (HTTP_HDR_REQ *) http_hdr_new(sizeof(HTTP_HDR_REQ));
		__hdr_init(hh);
		return hh;
	}

#ifdef	USE_TLS_EX
	pool = (ACL_ARRAY*) acl_pthread_tls_get(&cache_key);
	if (pool == NULL) {
		pool = acl_array_create(100);
		acl_pthread_tls_set(cache_key, pool,
			(void (*)(void*)) thread_cache_free);
	}

	pool = (ACL_ARRAY*) acl_pthread_tls_get(&cache_key);
	hh = (HTTP_HDR_REQ*) pool->pop_back(pool);
	if (hh) {
		__hdr_reset(hh, 1);
		http_hdr_reset((HTTP_HDR *) hh);
		return hh;
	}
#else
	acl_pthread_once(&once_control, cache_init);
	pool = (ACL_ARRAY*) acl_pthread_getspecific(cache_key);
	if (pool == NULL) {
		pool = acl_array_create(100);
		acl_pthread_setspecific(cache_key, pool);
		if ((unsigned long) acl_pthread_self() == acl_main_thread_self()) {
			cache_pool = pool;
			atexit(main_cache_free);
		}
	}
	hh = (HTTP_HDR_REQ*) pool->pop_back(pool);
	if (hh) {
		__hdr_reset(hh, 1);
		http_hdr_reset((HTTP_HDR *) hh);
		return hh;
	}
#endif

	hh = (HTTP_HDR_REQ *) http_hdr_new(sizeof(HTTP_HDR_REQ));
	__hdr_init(hh);
	return hh;
}
Ejemplo n.º 8
0
const char *acl_last_serror(void)
{
	char *buf;
	int   error = acl_last_error();
	static int __buf_size = 4096;

	(void) acl_pthread_once(&once_control, thread_buf_init);
	buf = acl_pthread_getspecific(__errbuf_key);
	if (buf == NULL) {
		buf = acl_mymalloc(__buf_size);
		acl_pthread_setspecific(__errbuf_key, buf);
		if ((unsigned long) acl_pthread_self() == acl_main_thread_self()) {
			__main_buf = buf;
			atexit(main_free_buf);
		}
	}
	return acl_strerror(error, buf, __buf_size);
}
Ejemplo n.º 9
0
	virtual bool thread_on_init()
	{
		acl_pthread_once(&stream_once, thread_init_once);
		acl::socket_stream* conn = (acl::socket_stream*)
			acl_pthread_getspecific(stream_key);
		if (conn != NULL)
			return true;

		conn = new acl::socket_stream;
		if (conn->bind_udp(var_cfg_local_addr) == false)
		{
			logger_error("bind %s error %s", var_cfg_local_addr,
				acl::last_serror());
			delete conn;
			return false;
		}

		acl_pthread_setspecific(stream_key, conn);
		return true;
	}
Ejemplo n.º 10
0
static ACL_MEM_SLICE *mem_slice_create(void)
{
	const char *myname = "mem_slice_create";
	ACL_MEM_SLICE *mem_slice;

	acl_pthread_once(&once_control, slice_key_init);

	if (__mem_slice_key == (acl_pthread_key_t) -1)
		acl_msg_fatal("%s(%d): __mem_slice_key(%d) invalid,"
			" call acl_mem_slice_init or acl_mem_slice_set first",
			myname, __LINE__, (int) __mem_slice_key);

	mem_slice = acl_pthread_getspecific(__mem_slice_key);
	if (mem_slice != NULL)
		return mem_slice;

	mem_slice = (ACL_MEM_SLICE*)
		acl_default_calloc(__FILE__, __LINE__, 1, sizeof(ACL_MEM_SLICE));
	if (mem_slice == NULL)
		acl_msg_fatal("%s(%d): can't alloc for mem_slice(%s)",
			myname, __LINE__, acl_last_serror());

	mem_slice->slice_pool = acl_slice_pool_create(__mem_base,
			__mem_nslice, __mem_slice_flag);
	mem_slice->tid = (unsigned long) acl_pthread_self();
	mem_slice->list = private_array_create(__mem_list_init_size);
	MUTEX_INIT(mem_slice);
	mem_slice->tls_key = __mem_slice_key;
	mem_slice->nalloc_gc = __mem_nalloc_gc;
	mem_slice->slice_flag = __mem_slice_flag;

	acl_pthread_setspecific(__mem_slice_key, mem_slice);

	if ((unsigned long) acl_pthread_self() == acl_main_thread_self())
		__main_mem_slice = mem_slice;

	acl_msg_info("%s(%d): thread(%ld) set myown mem_slice(%p)",
		myname, __LINE__, (long) mem_slice->tid, mem_slice);

	return mem_slice;
}
Ejemplo n.º 11
0
int acl_read_wait(ACL_SOCKET fd, int timeout)
{
    const char *myname = "acl_read_wait";
    int   delay = timeout * 1000, ret;
    EPOLL_CTX *epoll_ctx;
    struct epoll_event ee, events[1];
    time_t begin;

    acl_assert(acl_pthread_once(&epoll_once, thread_epoll_once) == 0);
    epoll_ctx = (EPOLL_CTX*) acl_pthread_getspecific(epoll_key);
    if (epoll_ctx == NULL)
        epoll_ctx = thread_epoll_init();

    ee.events = EPOLLIN | EPOLLHUP | EPOLLERR;
    ee.data.u64 = 0;
    ee.data.fd = fd;
    if (epoll_ctl(epoll_ctx->epfd, EPOLL_CTL_ADD, fd, &ee) == -1
            && acl_last_error() != EEXIST)
    {
        acl_msg_error("%s(%d): epoll_ctl error: %s, fd: %d, epfd: %d,"
                      " tid: %lu, %lu", myname, __LINE__, acl_last_serror(),
                      fd, epoll_ctx->epfd, epoll_ctx->tid,
                      acl_pthread_self());
        return -1;
    }

    for (;;) {
        time(&begin);

        ret = epoll_wait(epoll_ctx->epfd, events, 1, delay);
        if (ret == -1) {
            if (acl_last_error() == ACL_EINTR) {
                acl_msg_warn(">>>>catch EINTR, try again<<<");
                continue;
            }

            acl_msg_error("%s(%d): epoll_wait error: %s, fd: %d,"
                          " epfd: %d, tid: %lu, %lu", myname, __LINE__,
                          acl_last_serror(), fd, epoll_ctx->epfd,
                          epoll_ctx->tid, acl_pthread_self());
            ret = -1;
            break;
        } else if (ret == 0) {
            acl_msg_warn("%s(%d), %s: poll timeout: %s, fd: %d, "
                         "delay: %d, spent: %ld", __FILE__, __LINE__,
                         myname, acl_last_serror(), fd, delay,
                         (long) (time(NULL) - begin));
            acl_set_error(ACL_ETIMEDOUT);
            ret = -1;
            break;
        } else if ((events[0].events & (EPOLLERR | EPOLLHUP)) != 0) {
            acl_msg_warn("%s(%d), %s: poll error: %s, fd: %d, "
                         "delay: %d, spent: %ld", __FILE__, __LINE__,
                         myname, acl_last_serror(), fd, delay,
                         (long) (time(NULL) - begin));
            ret = -1;
        } else if ((events[0].events & EPOLLIN) == 0) {
            acl_msg_warn("%s(%d), %s: poll error: %s, fd: %d, "
                         "delay: %d, spent: %ld", __FILE__, __LINE__,
                         myname, acl_last_serror(), fd, delay,
                         (long) (time(NULL) - begin));
            acl_set_error(ACL_ETIMEDOUT);
            ret = -1;
        } else
            ret = 0;
        break;
    }

    ee.events = 0;
    ee.data.u64 = 0;
    ee.data.fd = fd;
    if (epoll_ctl(epoll_ctx->epfd, EPOLL_CTL_DEL, fd, &ee) == -1) {
        acl_msg_error("%s(%d): epoll_ctl error: %s, fd: %d, epfd: %d,"
                      " tid: %lu, %lu", myname, __LINE__, acl_last_serror(),
                      fd, epoll_ctx->epfd, epoll_ctx->tid,
                      acl_pthread_self());
        return -1;
    }

    return ret;
}
Ejemplo n.º 12
0
bool db_pgsql::dbopen(const char* /* charset = NULL */)
{
	if (conn_)
		return true;

	char  tmpbuf[256];
	char *db_host, *db_unix;
	int   db_port;

	char* ptr = strchr(dbaddr_, '/');
	if (ptr == NULL) {
		ACL_SAFE_STRNCPY(tmpbuf, dbaddr_, sizeof(tmpbuf));
		ptr = strchr(tmpbuf, ':');
		if (ptr == NULL || *(ptr + 1) == 0)
		{
			logger_error("invalid db_addr=%s", dbaddr_);
			return false;
		}
		else
			*ptr++ = 0;
		db_host = tmpbuf;

		db_port = atoi(ptr);
		if (db_port <= 0)
		{
			logger_error("invalid port=%d", db_port);
			return false;
		}
		db_unix = NULL;
	} else {
		db_unix = dbaddr_;
		db_host = db_unix;
		db_port = 0;
	}

	int* dummy;

	if (acl_pthread_once(&__thread_once_control, thread_once) != 0)
		logger_error("call thread_once error: %s", acl_last_serror());
	else if (!(dummy = (int*) acl_pthread_getspecific(__thread_key)))
	{
		dummy = (int*) acl_mymalloc(sizeof(int));
		*dummy = 1;
		acl_assert(!acl_pthread_setspecific(__thread_key, dummy));

		if ((unsigned long) acl_pthread_self()
			== acl_main_thread_self())
		{
			__main_dummy = dummy;
			atexit(main_free_dummy);
		}
	}

	string info;
	info.format("host=%s dbname=%s", db_host, dbname_);
	if (db_unix == NULL)
		info.format_append(" port=%d", db_port);
	if (dbuser_)
		info.format_append(" user=%s", dbuser_);
	if (dbpass_)
		info.format_append(" password=%s", dbpass_);

	conn_ = __dbconnect(info.c_str());
	if (conn_ == NULL || __dbstatus(conn_) != CONNECTION_OK)
	{
		logger_error("connect pgsql error(%s), db_host=%s, db_port=%d,"
			" db_unix=%s, db_name=%s, db_user=%s, db_pass=%s",
			conn_ ? __dberror_message(conn_) : "connect error",
			db_host ? db_host : "null", db_port,
			db_unix ? db_unix : "null",
			dbname_ ? dbname_ : "null",
			dbuser_ ? dbuser_ : "null",
			dbpass_ ? dbpass_ : "null");

		if (conn_)
		{
			__dbfinish(conn_);
			conn_ = NULL;
		}

		return false;
	}

	return true;
}
Ejemplo n.º 13
0
static void tls_mem_free(const char *filename, int line, void *ptr)
{
	MBLOCK *real_ptr;
	size_t len;

	CHECK_IN_PTR2(ptr, real_ptr, len, filename, line);

#if 1
	if (real_ptr->mem_slice->tid != (unsigned long) acl_pthread_self()) {
#else
	if (real_ptr->mem_slice->tid != mem_slice->tid) {
#endif
		MUTEX_LOCK(real_ptr->mem_slice);
		PRIVATE_ARRAY_PUSH(real_ptr->mem_slice->list, real_ptr);
		MUTEX_UNLOCK(real_ptr->mem_slice);
	} else
		acl_slice_pool_free(filename, line, real_ptr);
}

static void *tls_mem_alloc(const char *filename, int line, size_t len)
{
	const char *myname = "tls_mem_alloc";
	ACL_MEM_SLICE *mem_slice = acl_pthread_getspecific(__mem_slice_key);
	char *ptr;
	MBLOCK *real_ptr;

	if (mem_slice == NULL) {
		/* 每个子线程获得自己的线程局部存储内存池 */
		mem_slice = mem_slice_create();
		mem_slice->slice_list = __mem_slice_list;

		/* 将子线程的线程局部存储内存池置入全局内存池句柄集合中 */
		if (__mem_slice_list_lock)
			thread_mutex_lock(__mem_slice_list_lock);
		private_array_push(__mem_slice_list, mem_slice);
		if (__mem_slice_list_lock)
			thread_mutex_unlock(__mem_slice_list_lock);
	}

	real_ptr = (MBLOCK *) acl_slice_pool_alloc(filename, line,
			mem_slice->slice_pool, SPACE_FOR(len));
	if (real_ptr == 0) {
		acl_msg_error("%s(%d): malloc: insufficient memory",
			myname, __LINE__);
		return 0;
	}

	mem_slice->nalloc++;
	if (mem_slice->nalloc == mem_slice->nalloc_gc) {
		mem_slice->nalloc = 0;
		mem_slice_gc(mem_slice);
	}
	CHECK_OUT_PTR(ptr, real_ptr, mem_slice, len);
	return ptr;
}

static void *tls_mem_calloc(const char *filename, int line, size_t nmemb, size_t size)
{
	void *ptr = tls_mem_alloc(filename, line, nmemb * size);

	memset(ptr, 0, nmemb * size);
	return ptr;
}
Ejemplo n.º 14
0
bool db_mysql::dbopen(const char* charset /* = NULL */)
{
	if (conn_)
		return true;

	char  tmpbuf[256];
	char *db_host, *db_unix;
	int   db_port;

	char* ptr = strchr(dbaddr_, '/');
	if (ptr == NULL) {
		ACL_SAFE_STRNCPY(tmpbuf, dbaddr_, sizeof(tmpbuf));
		ptr = strchr(tmpbuf, ':');
		if (ptr == NULL || *(ptr + 1) == 0)
		{
			logger_error("invalid db_addr=%s", dbaddr_);
			return false;
		}
		else
			*ptr++ = 0;
		db_host = tmpbuf;

		db_port = atoi(ptr);
		if (db_port <= 0)
		{
			logger_error("invalid port=%d", db_port);
			return false;
		}
		db_unix = NULL;
	} else {
		db_unix = dbaddr_;
		db_host = NULL;
		db_port = 0;
	}

	int* dummy;

	if (acl_pthread_once(&__thread_once_control, thread_once) != 0)
		logger_error("call thread_once error: %s", acl_last_serror());
	else if (!(dummy = (int*) acl_pthread_getspecific(__thread_key)))
	{
		dummy = (int*) acl_mymalloc(sizeof(int));
		*dummy = 1;
		acl_assert(!acl_pthread_setspecific(__thread_key, dummy));

		// 调用下面函数可能会造成内存越界
		//if (__mysql_thread_init != NULL)
		//	__mysql_thread_init();

		if ((unsigned long) acl_pthread_self()
			== acl_main_thread_self())
		{
			__main_dummy = dummy;
			atexit(main_free_dummy);
		}
	}

	conn_ = __mysql_init(NULL);
	if (conn_ == NULL)
	{
		logger_error("mysql init error");
		return false;
	}

	if (conn_timeout_ > 0)
#if MYSQL_VERSION_ID >= 50500
		__mysql_options(conn_, MYSQL_OPT_CONNECT_TIMEOUT,
			(const void*) &conn_timeout_);
#else
		__mysql_options(conn_, MYSQL_OPT_CONNECT_TIMEOUT,
			(const char*) &conn_timeout_);
#endif

	if (rw_timeout_ > 0)
	{
#if MYSQL_VERSION_ID >= 50500
		__mysql_options(conn_, MYSQL_OPT_READ_TIMEOUT,
			(const void*) &rw_timeout_);
		__mysql_options(conn_, MYSQL_OPT_WRITE_TIMEOUT,
			(const void*) &rw_timeout_);
#else
		__mysql_options(conn_, MYSQL_OPT_READ_TIMEOUT,
			(const char*) &rw_timeout_);
		__mysql_options(conn_, MYSQL_OPT_WRITE_TIMEOUT,
			(const char*) &rw_timeout_);
#endif
	}

	my_bool reconnect = 1;

#if MYSQL_VERSION_ID >= 50500
	__mysql_options(conn_, MYSQL_OPT_RECONNECT, (const void*) &reconnect);
#else
	__mysql_options(conn_, MYSQL_OPT_RECONNECT, (const char*) &reconnect);
#endif

	if (__mysql_open(conn_, db_host, dbuser_ ? dbuser_ : "",
		dbpass_ ? dbpass_ : "", dbname_, db_port,
		db_unix, dbflags_) == NULL)
	{
		logger_error("connect mysql error(%s), db_host=%s, db_port=%d,"
			" db_unix=%s, db_name=%s, db_user=%s, db_pass=%s,"
			" dbflags=%ld",
			__mysql_error(conn_),
			db_host ? db_host : "null", db_port,
			db_unix ? db_unix : "null",
			dbname_ ? dbname_ : "null",
			dbuser_ ? dbuser_ : "null",
			dbpass_ ? dbpass_ : "null", dbflags_);

		__mysql_close(conn_);
		conn_ = NULL;
		return false;
	}
#if 0
	logger("connect mysql ok(%s), db_host=%s, db_port=%d, "
		"db_unix=%s, db_name=%s, db_user=%s, db_pass=%s, dbflags=%ld",
		__mysql_error(conn_),
		db_host ? db_host : "null", db_port,
		db_unix ? db_unix : "null",
		dbname_ ? dbname_ : "null",
		dbuser_ ? dbuser_ : "null",
		dbpass_ ? dbpass_ : "null", dbflags_);
#endif

	if (charset != NULL && *charset != 0)
		charset_ = charset;

	if (!charset_.empty())
	{
		if (!__mysql_set_character_set(conn_, charset_.c_str()))
			logger("set mysql charset to %s, %s", charset_.c_str(),
				__mysql_character_set_name(conn_));
		else
			logger_error("set mysql to %s error %s",
				charset_.c_str(), __mysql_error(conn_));
	}

#if MYSQL_VERSION_ID >= 50000
	if (__mysql_autocommit(conn_, auto_commit_ ? 1 : 0) != 0)
	{
		logger_error("mysql_autocommit error");
		__mysql_close(conn_);
		conn_ = NULL;
		return (false);
	}
#else
	auto_commit_ = false;
#endif

	return true;
}