[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[Libevent-users] Does bufferevent_openssl_socket_new() API support multi-thread?
- To: libevent-users@xxxxxxxx
- Subject: [Libevent-users] Does bufferevent_openssl_socket_new() API support multi-thread?
- From: 林宇舜 Yu-Shun Lin <ys.ncku@xxxxxxxxx>
- Date: Sun, 9 Jan 2011 23:35:20 +0800
- Delivered-to: archiver@xxxxxxxx
- Delivered-to: libevent-users-outgoing@xxxxxxxx
- Delivered-to: libevent-users@xxxxxxxx
- Delivery-date: Sun, 09 Jan 2011 10:35:28 -0500
- Dkim-signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:mime-version:received:received:date:message-id :subject:from:to:content-type; bh=1VMnYPDkpCUct+vQcwuVXF4vSVZefucluw9wn+6pTeE=; b=N00UBVCf9ir645VBTk1XO+Ixsuj6sDapiOLu5M+YcYzfWqNtGASqDaNICq3WHFXKHw YtVB20SuvN0B2DW1aY23HnIQeMNygquH6kR16oLa40+ELEiaRPJEINgDqflOd2i/0c3i xaCvJWwUazCoSd2GYevArEvr3L7/QxpQc+fNY=
- Domainkey-signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=mime-version:date:message-id:subject:from:to:content-type; b=Nz0E92xQ5LiyLZq5+Spcw5qIj4LDK33I5fmRxY0xWi72FvSI1d81oI1cGDL6llGaSk xeTQYq1uKaK9B/kX/JD+QvSF5Z1kYCj0PGV57PsdllOA0fafDpEcl2BA+Xb1bINe/cmb bghG1bg6RlIpYaeDFGmXizuaO2W209KR3n35E=
- Reply-to: libevent-users@xxxxxxxxxxxxx
- Sender: owner-libevent-users@xxxxxxxxxxxxx
Hi all.
Does bufferevent_openssl_socket_new() API support multi-thread?
I refer the sample of regress_ssl.c in the libevent source package, and write an SSL server with multi-thread.
But it is deadlock after receive the first message from client.
Anyone have idea?
Thanks!
Brian
==
Here is the function stack at last:
(gdb) thread apply all bt
Thread 2 (Thread 0x40a00940 (LWP 30815)):
#0 0x00000034bbe0aee9 in pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0
#1 0x00002aaaaacfdf7e in evthread_posix_cond_wait (_cond=0x6039a0, _lock=0x603520, tv=0x0) at evthread_pthread.c:164
#2 0x00002aaaaaabdfc7 in event_del_internal (ev=0x6a2308) at event.c:2142
#3 0x00002aaaaaabde47 in event_del (ev=0x6a2308) at event.c:2110
#4 0x00002aaaaaf01f32 in consider_writing (bev_ssl=0x6a2270) at bufferevent_openssl.c:780
#5 0x00002aaaaaf027de in be_openssl_outbuf_cb (buf=0x6a2550, cbinfo=0x409ffff0, arg=0x6a2270) at bufferevent_openssl.c:1013
#6 0x00002aaaaaac141d in evbuffer_run_callbacks (buffer=0x6a2550, running_deferred=0) at buffer.c:443
#7 0x00002aaaaaac1f88 in evbuffer_invoke_callbacks (buffer=0x6a2550) at buffer.c:460
#8 0x00002aaaaaac4532 in evbuffer_add (buf=0x6a2550, data_in=0x401a78, datlen=94) at buffer.c:1557
#9 0x00002aaaaaac8238 in bufferevent_write (bufev=0x6a2270, data="" size=94) at bufferevent.c:376
#10 0x0000000000401330 in thread_write (arg=0x0) at bev_ssl.c:29
#11 0x00000034bbe0673d in start_thread () from /lib64/libpthread.so.0
#12 0x00000034bb6d3f6d in clone () from /lib64/libc.so.6
Thread 1 (Thread 0x2aaaab11ddd0 (LWP 30812)):
#0 0x00000034bbe0d4c4 in __lll_lock_wait () from /lib64/libpthread.so.0
#1 0x00000034bbe08e35 in _L_lock_1127 () from /lib64/libpthread.so.0
#2 0x00000034bbe08d33 in pthread_mutex_lock () from /lib64/libpthread.so.0
#3 0x00002aaaaacfdd56 in evthread_posix_lock (mode=0, _lock=0x624070) at evthread_pthread.c:78
#4 0x00002aaaaaac88f5 in _bufferevent_incref_and_lock (bufev=0x6a2270) at bufferevent.c:561
#5 0x00002aaaaaf020a6 in be_openssl_writeeventcb (fd=11, what=4, ptr=0x6a2270) at bufferevent_openssl.c:842
#6 0x00002aaaaaabb68f in event_persist_closure (base=0x6035a0, ev=0x6a2308) at event.c:1238
#7 0x00002aaaaaabb281 in event_process_active_single_queue (base=0x6035a0, activeq=0x603500) at event.c:1282
#8 0x00002aaaaaabb852 in event_process_active (base=0x6035a0) at event.c:1354
#9 0x00002aaaaaabbe48 in event_base_loop (base=0x6035a0, flags=0) at event.c:1551
#10 0x00002aaaaaabb8cd in event_base_dispatch (event_base=0x6035a0) at event.c:1382
#11 0x00000000004016e7 in main () at bev_ssl.c:176
==
Here is my code:
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <event.h>
#include <event2/listener.h>
#include <event2/bufferevent_ssl.h>
#include <event2/thread.h>
#include <openssl/ssl.h>
#include <pthread.h>
#include "const.h"
#include "bev.h"
#include "ssl.h"
struct event_base *evbase;
SSL_CTX *g_ssl_ctx = NULL;
struct bufferevent *bev = NULL;
int flag = 0;
void *thread_write(void *arg)
{
while (1) {
if (flag) {
if (bev != NULL) {
bufferevent_write(bev, RESPONSE, strlen(RESPONSE));
}
flag = 0;
}
usleep(1000 * 1000 * 0.1);
}
}
/*
* read_cb()
*/
static void read_cb(struct bufferevent *bev, void *arg)
{
char buff[BUFF_SIZE] = {0}; // tmp buff
/* Read data */
memset(buff, 0, sizeof(buff));
bufferevent_read(bev, buff, sizeof(buff));
fprintf(stderr, "Recv[%s]\n", buff);
flag = 1;
}
/*
* event_cb()
*/
static void event_cb(struct bufferevent *bev, short events, void *arg)
{
if (events & BEV_EVENT_CONNECTED) {
/* Do nothing here. */
fprintf(stderr, "events[BEV_EVENT_CONNECTED]\n");
} else {
fprintf(stderr, "events[%d]\n", events);
/* Close conn. */
bufferevent_free(bev);
bev = NULL;
}
}
/*
* accept_cb()
*/
static void accept_cb(struct evconnlistener *lev,
evutil_socket_t fd, struct sockaddr *sa,
int socklen, void *ctx)
{
SSL *ssl;
if ((ssl = SSL_new(g_ssl_ctx)) == NULL) {
goto err_ret;
}
/* Create security socket-based buffer event. */
if ((bev = bufferevent_openssl_socket_new(evbase, fd, ssl,
BUFFEREVENT_SSL_ACCEPTING,
BEV_OPT_CLOSE_ON_FREE|BEV_OPT_THREADSAFE))
== NULL) {
fprintf(stderr, "Cannot create bufferevent control socket");
goto err_ret;
}
/* Set up callback functions. */
bufferevent_setcb(bev, read_cb, NULL, event_cb, NULL);
/* Enable read/write event. */
bufferevent_enable(bev, EV_READ | EV_WRITE);
return;
err_ret:
evutil_closesocket(fd);
}
/*
* server_init()
*/
int server_init()
{
struct sockaddr_in sin; // connection address
uint32_t flags; // socket options
struct evconnlistener *lev;
/* Set up connection address. */
memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = inet_addr(SVR_IP);
sin.sin_port = htons(SVR_PORT);
/* Bind listen socket. */
flags = (LEV_OPT_REUSEABLE | LEV_OPT_CLOSE_ON_FREE | LEV_OPT_THREADSAFE);
lev = evconnlistener_new_bind(evbase, accept_cb, NULL,
flags, -1,
(struct sockaddr *)&sin, sizeof(sin));
return(lev ? 0 : -1);
}
/*
* main()
*/
int main(void)
{
pthread_t tid;
/* Set up libevent to work with pthread. */
if (evthread_use_pthreads() < 0) {
fprintf(stderr, "evthread_use_pthreads() fail\n");
return -1;
}
/* Initialize event base. */
if ((evbase = event_base_new()) == NULL) {
DEBUG("Cannot create event base\n");
return -1;
}
/* Allow other thread to wake up event base. */
if (evthread_make_base_notifiable(evbase) < 0) {
fprintf(stderr, "Cannot make event base notifiable");
return -1;
}
/* Init. SSL */
if (init_ssl() != 0) {
fprintf(stderr, "Cannot init SSL\n");
return -1;
}
/* Thread init */
if (pthread_create(&tid, NULL, thread_write, NULL) != 0) {
fprintf(stderr, "pthread_create() failed\n");
return -1;
}
/* Set listener */
if (server_init() != 0) {
DEBUG("Cannot init server\n");
return -1;
}
/*
* Event loop
*/
event_base_dispatch(evbase);
/* End of program */
SSL_CTX_free(g_ssl_ctx);
return 0;
}