If I replace the thread code, and it works. It seems somewhere has
problem with multiple threads.
On 03/18/2016 10:13 PM, Michael wrote:
Hi all,
I tried to use pthread to work with libevent. But the server can't
send out data after recving a message. The detail is:
I can see that the data has been put into the evbuffer (output)
using evbuffer_add_cb(bufferevent_get_output(bev_),
BufferCb, tp): BufferCb info->orig_size: 0
info->n_deleted: 0 info->n_added: 19
But the underlying level didn't send out
the data. and when another client coming, the server has no
response (listener callback doesn't work). But when I close
the server (kill the process), client can recv close signal.
I apt-get install libevent, and the version is :
libevent-core-2.0-5_2.0.21-stable-1ubuntu1.14.04.1_amd64
What's the problem? Thanks!!!
[server init]:
bev_ = bufferevent_socket_new(base_, fd,
BEV_OPT_CLOSE_ON_FREE|BEV_OPT_THREADSAFE);
// set read callback and event callback
bufferevent_setcb(bev_, ReadCb, NULL, EventCb, this);
bufferevent_enable(bev_, EV_READ | EV_WRITE);
[server read callback]:
bev_ = bufferevent_socket_new(base_, fd,
BEV_OPT_CLOSE_ON_FREE|BEV_OPT_THREADSAFE);
// set read callback and event callback
bufferevent_setcb(bev_, ReadCb, NULL, EventCb, this);
bufferevent_enable(bev_, EV_READ | EV_WRITE);
// read is ok
bufferevent_lock(bev_);
struct evbuffer *input = bufferevent_get_input(bev_);
return evbuffer_remove(input, buffer, len);
bufferevent_unlock(bev_);
// process read data..........
// write has problem
bufferevent_lock(bev_);
struct evbuffer *output = bufferevent_get_output(bev_);
int re = evbuffer_add(output, buffer, len);
bufferevent_unlock(bev_);
[server event_base set]:
void Listener::Run(void* arg) {
struct sockaddr_in sin;
/* Clear the sockaddr before using it, in case there are extra
* * platform-specific fields that can mess us up. */
memset(&sin, 0, sizeof(sin));
/* This is an INET address */
sin.sin_family = AF_INET;
/* Listen on 0.0.0.0 */
sin.sin_addr.s_addr = htonl(INADDR_ANY);
/* Listen on the given port. */
sin.sin_port = htons(port_);
// TODO: LEV_OPT_THREADSAFE is necessary here?
listener_ = evconnlistener_new_bind(listen_base_,
AcceptConnCb, arg,
LEV_OPT_CLOSE_ON_FREE|LEV_OPT_REUSEABLE|LEV_OPT_THREADSAFE, -1,
(struct sockaddr*)&sin, sizeof(sin));
if (!listener_) {
LOG_ERROR("Couldn't create listener");
return;
}
evconnlistener_set_error_cb(listener_, AcceptErrorCb);
event_base_dispatch(listen_base_);
return;
}
On 03/17/2016 08:50 PM, Azat Khuzhin
wrote:
On Thu, Mar 17, 2016 at 05:14:22PM +0000, Tomer Heber wrote:
Hi Azat,
Correct me if I'm wrong.
Hi Tomer,
Indeed,
But he is using std c++11 "libraries" which are cross platform.
but if don't talking about cross platform then pthreads are ok on *nix,
and for win32 we have evthread_use_windows_threads()
But if you need cross platform, then you can just write something like
this (untested):
#include <mutex>
/** XXX: implement handle recursive locking! */
static void *cxx_lock_alloc(unsigned /*locktype*/)
{
return reinterpret_cast<void *>(new std::mutex);
}
static void cxx_lock_free(void *lock_, unsigned /*locktype*/)
{
std::mutex *m = reinterpret_cast<std::mutex *>(lock_);
delete m;
}
static int cxx_lock_lock(unsigned /*mode*/, void *lock_)
{
std::mutex *m = reinterpret_cast<std::mutex *>(lock_);
m->lock();
}
static int cxx_lock_unlock(unsigned /*mode*/, void *lock_)
{
std::mutex *m = reinterpret_cast<std::mutex *>(lock_);
m->unlock();
}
static int use_lock_unlock_profiler(void)
{
struct evthread_lock_callbacks cbs = {
EVTHREAD_LOCK_API_VERSION,
EVTHREAD_LOCKTYPE_RECURSIVE,
cxx_lock_alloc,
cxx_lock_free,
cxx_lock_lock,
cxx_lock_unlock,
};
evthread_set_lock_callbacks(&cbs);
// evthread_enable_lock_debugging();
Also you can take a look at
https://github.com/libevent/libevent/blob/master/test/regress_bufferevent.c#L300
On the other hand, pthread is not cross platform.
So I think Michael shouldn't use pthreads and instead implement the callbacks (which is actually pretty straightforward).
***********************************************************************
To unsubscribe, send an e-mail to majordomo@xxxxxxxxxxxxx with
unsubscribe libevent-users in the body.
|