示例#1
0
文件: fiber_io.c 项目: QianErGe/acl
void fiber_io_check(void)
{
	if (__thread_fiber != NULL)
		return;

	acl_assert(acl_pthread_once(&__once_control, thread_init) == 0);

	__maxfd = acl_open_limit(0);
	if (__maxfd <= 0)
		__maxfd = MAXFD;

	__thread_fiber = (FIBER_TLS *) acl_mymalloc(sizeof(FIBER_TLS));
	__thread_fiber->event = event_create(__maxfd);
	__thread_fiber->io_fibers = (ACL_FIBER **)
		acl_mycalloc(__maxfd, sizeof(ACL_FIBER *));
	__thread_fiber->ev_fiber = acl_fiber_create(fiber_io_loop,
			__thread_fiber->event, STACK_SIZE);
	__thread_fiber->io_count = 0;
	__thread_fiber->nsleeping = 0;
	__thread_fiber->io_stop = 0;
	acl_ring_init(&__thread_fiber->ev_timer);

	if ((unsigned long) acl_pthread_self() == acl_main_thread_self()) {
		__main_fiber = __thread_fiber;
		atexit(fiber_io_main_free);
	} else if (acl_pthread_setspecific(__fiber_key, __thread_fiber) != 0)
		acl_msg_fatal("acl_pthread_setspecific error!");
}
示例#2
0
db_mysql::db_mysql(const char* dbaddr, const char* dbname,
	const char* dbuser, const char* dbpass,
	unsigned long dbflags /* = 0 */, bool auto_commit /* = true */,
	int conn_timeout /* = 60 */, int rw_timeout /* = 60 */)
{
	acl_assert(dbaddr && *dbaddr);
	acl_assert(dbname && *dbname);
	dbaddr_ = acl_mystrdup(dbaddr);
	dbname_ = acl_mystrdup(dbname);

	if (dbuser)
		dbuser_ = acl_mystrdup(dbuser);
	else
		dbuser_ = NULL;

	if (dbpass)
		dbpass_ = acl_mystrdup(dbpass);
	else
		dbpass_ = NULL;

	dbflags_ = dbflags;
	auto_commit_ = auto_commit;
	conn_timeout_ = conn_timeout;
	rw_timeout_ = rw_timeout;

#if defined(ACL_CPP_DLL) || defined(USE_DYNAMIC)
	acl_pthread_once(&__mysql_once, __mysql_dll_load);
#endif
	conn_ = NULL;
}
示例#3
0
int acl_xml_decode(const char *in, ACL_VSTRING *out)
{
    int   n = 0, len;
    const char *ptr = in, *pre;
    const ACL_TOKEN *token;
    const XML_SPEC *spec;

    acl_pthread_once(&__token_once, xml_decode_init);
    if (__token_tree == NULL)
        acl_msg_fatal("__token_tree null");

    while (*ptr != 0) {
        pre = ptr;
        token = acl_token_tree_match(__token_tree, &ptr, NULL, NULL);
        if (token == NULL) {
            pre = markup_unescape(pre, out);
            len = (int) (ptr - pre);
            if (len > 0)
                acl_vstring_memcat(out, pre, len);
            break;
        }
        spec = (const XML_SPEC*) token->ctx;
        acl_assert(spec != NULL);

        len = (int) (ptr - pre - spec->len);
        if (len > 0)
            acl_vstring_memcat(out, pre, len);
        acl_vstring_strcat(out, spec->str);
        n++;
    }

    ACL_VSTRING_TERMINATE(out);
    return (n);
}
示例#4
0
static void fiber_check(void)
{
	if (__thread_fiber != NULL)
		return;

	acl_assert(acl_pthread_once(&__once_control, thread_init) == 0);

	__thread_fiber = (FIBER_TLS *) acl_mycalloc(1, sizeof(FIBER_TLS));
#ifdef	USE_JMP
	/* set context NULL when using setjmp that setcontext will not be
	 * called in fiber_swap.
	 */
	__thread_fiber->original.context = NULL;
#else
	__thread_fiber->original.context = (ucontext_t *)
		acl_mycalloc(1, sizeof(ucontext_t));
#endif
	__thread_fiber->fibers = NULL;
	__thread_fiber->size   = 0;
	__thread_fiber->slot   = 0;
	__thread_fiber->idgen  = 0;
	__thread_fiber->count  = 0;

	acl_ring_init(&__thread_fiber->ready);
	acl_ring_init(&__thread_fiber->dead);

	if ((unsigned long) acl_pthread_self() == acl_main_thread_self()) {
		__main_fiber = __thread_fiber;
		atexit(fiber_schedule_main_free);
	} else if (acl_pthread_setspecific(__fiber_key, __thread_fiber) != 0)
		acl_msg_fatal("acl_pthread_setspecific error!");
}
示例#5
0
void db_pgsql::load(void)
{
#ifdef HAS_PGSQL_DLL
	acl_pthread_once(&__pgsql_once, __pgsql_dll_load);
#else
	logger_warn("link pgsql library in static way!");
#endif
}
示例#6
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;
}
示例#7
0
文件: acl_init.c 项目: 2202877/acl
unsigned long acl_main_thread_self()
{
#ifdef ACL_UNIX
	return ((unsigned long) acl_var_main_tid);
#elif defined(WIN32)
	if (acl_var_main_tid == (unsigned long) -1)
		acl_pthread_once(&__once_control, get_main_thread_id);
	return (acl_var_main_tid);
#else
#error "Unknown OS"
#endif
}
示例#8
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;
}
示例#9
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;
}
示例#10
0
const char *acl_xml_decode2(const char *in, char **out, size_t *size)
{
    size_t len;
    const char *ptr = in, *pre;
    const ACL_TOKEN *token;
    const XML_SPEC *spec;

    if (*size == 0)
        return in;

    *size -= 1;  /* reserve space for '\0' */

    acl_pthread_once(&__token_once, xml_decode_init);
    if (__token_tree == NULL)
        acl_msg_fatal("__token_tree null");

    while (*ptr != 0) {
        pre = ptr;
        token = acl_token_tree_match(__token_tree, &ptr, NULL, NULL);
        if (token == NULL) {
            pre = markup_unescape2(pre, out, size);
            if (*size == 0)
                break;

            if (ptr > pre)
                (void) copy_buf(out, size, pre, ptr - pre);
            break;
        }

        spec = (const XML_SPEC*) token->ctx;
        acl_assert(spec != NULL);

        len = ptr - pre - spec->len;
        if (len > 0)
            copy_buf(out, size, pre, len);

        if (*size == 0)
            break;

        (void) copy_buf(out, size, spec->str, strlen(spec->str));
        if (*size == 0)
            break;
    }

    **out = '\0';
    *out += 1;
    return ptr;
}
示例#11
0
charset_conv::charset_conv()
: m_addInvalid(true)
, m_errmsg("ok")
, m_pBuf(NULL)
{
	m_fromCharset[0] = 0;
	m_toCharset[0] = 0;
#ifdef  HAVE_H_ICONV
	m_iconv = (iconv_t) -1;
	m_pInBuf = NULL;
	m_pOutBuf = NULL;
# ifdef WIN32 
#  ifndef USE_WIN_ICONV
	acl_pthread_once(&__iconv_once, __iconv_dll_load);
#  endif
# endif
#endif
}
示例#12
0
文件: acl_msg.c 项目: shitfSign/acl
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);
}
示例#13
0
文件: db_mysql.cpp 项目: iYefeng/acl
void db_mysql::sane_mysql_init(const char* dbaddr, const char* dbname,
	const char* dbuser, const char* dbpass,
	unsigned long dbflags, bool auto_commit,
	int conn_timeout, int rw_timeout,
	const char* charset)
{
	if (dbaddr == NULL || *dbaddr == 0)
		logger_fatal("dbaddr null");
	if (dbname == NULL || *dbname == 0)
		logger_fatal("dbname null");

	// 地址格式:[dbname@]dbaddr
	const char* ptr = strchr(dbaddr, '@');
	if (ptr)
		ptr++;
	else
		ptr = dbaddr;
	acl_assert(*ptr);
	dbaddr_ = acl_mystrdup(ptr);
	dbname_ = acl_mystrdup(dbname);

	if (dbuser && *dbuser)
		dbuser_ = acl_mystrdup(dbuser);
	else
		dbuser_ = NULL;

	if (dbpass && *dbpass)
		dbpass_ = acl_mystrdup(dbpass);
	else
		dbpass_ = NULL;

	if (charset && *charset)
		charset_ = charset;

	dbflags_      = dbflags;
	auto_commit_  = auto_commit;
	conn_timeout_ = conn_timeout;
	rw_timeout_   = rw_timeout;

#ifdef HAS_MYSQL_DLL
	acl_pthread_once(&__mysql_once, __mysql_dll_load);
#endif
	conn_ = NULL;
}
示例#14
0
void db_pgsql::sane_pgsql_init(const char* dbaddr, const char* dbname,
	const char* dbuser, const char* dbpass, int conn_timeout,
	int rw_timeout, const char* charset)
{
	affect_count_ = 0;

	if (dbaddr == NULL || *dbaddr == 0)
		logger_fatal("dbaddr null");
	if (dbname == NULL || *dbname == 0)
		logger_fatal("dbname null");

	// 地址格式:[dbname@]dbaddr
	const char* ptr = strchr(dbaddr, '@');
	if (ptr)
		ptr++;
	else
		ptr = dbaddr;
	acl_assert(*ptr);
	dbaddr_ = acl_mystrdup(ptr);
	dbname_ = acl_mystrdup(dbname);

	if (dbuser && *dbuser)
		dbuser_ = acl_mystrdup(dbuser);
	else
		dbuser_ = NULL;

	if (dbpass && *dbpass)
		dbpass_ = acl_mystrdup(dbpass);
	else
		dbpass_ = NULL;

	if (charset && *charset)
		charset_ = charset;

	conn_timeout_ = conn_timeout;
	rw_timeout_   = rw_timeout;

#ifdef HAS_PGSQL_DLL
	acl_pthread_once(&__pgsql_once, __pgsql_dll_load);
#endif
	conn_ = NULL;
}
示例#15
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;
	}
示例#16
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;
}
示例#17
0
int acl_pthread_key_create(acl_pthread_key_t *key_ptr,
	void (*destructor)(void*))
{
	const char *myname = "acl_pthread_key_create";

	acl_pthread_once(&__create_thread_control_once, acl_pthread_init_once);

	*key_ptr = TlsAlloc();
	if (*key_ptr == ACL_TLS_OUT_OF_INDEXES) {
		acl_set_error(ACL_ENOMEM);
		return ACL_ENOMEM;
	} else if (*key_ptr >= ACL_PTHREAD_KEYS_MAX) {
		acl_msg_error("%s(%d): key(%d) > ACL_PTHREAD_KEYS_MAX(%d)",
			myname, __LINE__, *key_ptr, ACL_PTHREAD_KEYS_MAX);
		TlsFree(*key_ptr);
		*key_ptr = ACL_TLS_OUT_OF_INDEXES;
		acl_set_error(ACL_ENOMEM);
		return ACL_ENOMEM;
	}

	__tls_key_list[*key_ptr].destructor = destructor;
	__tls_key_list[*key_ptr].key = *key_ptr;
	return 0;
}
示例#18
0
int  acl_pthread_create(acl_pthread_t *thread, acl_pthread_attr_t *attr,
	void *(*start_routine)(void *), void *arg)
{
	const char *myname = "acl_pthread_create";
	acl_pthread_t *h_thread;
	HANDLE handle;
	unsigned long id, flag;
	
	if (thread == NULL) {
		acl_msg_error("%s, %s(%d): input invalid",
			__FILE__, myname, __LINE__);
		acl_set_error(ACL_EINVAL);
		return ACL_EINVAL;
	}
	acl_pthread_once(&__create_thread_control_once, acl_pthread_init_once);
	memset(thread, 0, sizeof(acl_pthread_t));

	h_thread = acl_default_calloc(__FILE__, __LINE__,
			1, sizeof(acl_pthread_t));
	if (h_thread == NULL) {
		acl_msg_error("%s, %s(%d): calloc error(%s)",
			__FILE__, myname, __LINE__, acl_last_serror());
		acl_set_error(ACL_ENOMEM);
		return ACL_ENOMEM;
	}

	if (attr != NULL)
		h_thread->detached = attr->detached;
	else
		h_thread->detached = 1;
	h_thread->start_routine = start_routine;
	h_thread->routine_arg   = arg;

	if (__thread_inited) {
		acl_pthread_mutex_lock(&__thread_lock);
		flag = 0;
	} else
		flag = CREATE_SUSPENDED;

#ifdef ACL_WIN32_STDC
	h_thread->handle = handle = (HANDLE) _beginthreadex(NULL,
			attr ? (unsigned int) attr->stacksize : 0,
			RunThreadWrap,
			(void *) h_thread,
			flag,
			&id);
#else
	h_thread->handle = handle = CreateThread(NULL,
			attr ? attr->stacksize : 0,,
			RunThreadWrap,
			h_thread,
			flag,
			&id);
#endif

	if (__thread_inited)
		acl_pthread_mutex_unlock(&__thread_lock);
	else if (flag == CREATE_SUSPENDED && handle != 0)
		ResumeThread(handle);
	if (handle == 0) {
		acl_msg_error("%s, %s(%d): CreateThread error(%s)",
			__FILE__, myname, __LINE__, acl_last_serror());
		return -1;
	}
	thread->start_routine = start_routine;
	thread->routine_arg   = arg;
	thread->id            = id;
	thread->handle        = 0;

	/* 根据线程的属性来确定线程创建时是分离模式还是非分离模式 */

	if (attr == NULL || attr->detached) {
		thread->detached = 1;
		return 0;
	}

	thread->detached = 0;
	thread->handle = handle;
	return 0;
}
示例#19
0
文件: acl_read_wait.c 项目: xmszt/acl
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;
}
示例#20
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;
}
示例#21
0
文件: db_mysql.cpp 项目: iYefeng/acl
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;
}