The listener indeed helps me to reduce the coding efforts. However, what I want to do is still not working.
Is it possible to bind several connections to a base and dispatch event of the base in a new thread? So I use main function to accept the connection and add this fd to a base running in another thread? Thanks, Fang 2016-03-23 19:08 GMT-04:00 Tim Chou <[email protected]>: > Hi Michael, > > Thank you so much. > > After reading the example, I realize the listener is the right way to bind > new connections to the base. > > I will try this way. > > Thanks, again. > Fang > > > 2016-03-23 18:48 GMT-04:00 Michael (Tieying) Zhang <[email protected]>: > >> Hi Fang, >> >> I think you can use the example code from the documentation, and you >> don't need to set it nonblocking manually in this way. >> >> >> *struct* event_base *base; >> *struct* evconnlistener *listener; >> *struct* sockaddr_in sin; >> >> *int* port = 9876; >> >> *if* (argc > 1) { >> port = atoi(argv[1]); >> } >> *if* (port<=0 || port>65535) { >> puts("Invalid port"); >> *return* 1; >> } >> >> base = event_base_new(); >> *if* (!base) { >> puts("Couldn't open event base"); >> *return* 1; >> } >> * /* 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(0);* /* Listen on the given port. >> */* >> sin.sin_port = htons(port); >> >> listener = evconnlistener_new_bind(base, accept_conn_cb, NULL, >> LEV_OPT_CLOSE_ON_FREE|LEV_OPT_REUSEABLE, -1, >> (*struct* sockaddr*)&sin, *sizeof*(sin)); >> *if* (!listener) { >> perror("Couldn't create listener"); >> *return* 1; >> } >> evconnlistener_set_error_cb(listener, accept_error_cb); >> >> event_base_dispatch(base); >> >> >> ------------------------------ >> [email protected] >> >> *From:* Tim Chou <[email protected]> >> *Date:* 2016-03-23 18:31 >> *To:* libevent-users <[email protected]> >> *Subject:* [Libevent-users] Add multiples bufferevents on one base then >> lead to some errors. >> Hi all, >> >> Sorry to disturb you. >> I'm writing a server. I plan to use one thread serving ten connections. >> I use bufferevent_setcb to register 10 sockets to one base. I also use a >> global variable to count the number. >> >> I think I can register the bufferevent on one base before I start a >> pthread to dispatch(). >> However, I always get the error: [err] event_queue_insert: 0x146dfc8(fd >> 32) already on queue 2 >> >> If I create one thread for one base with only one bufferevent, then the >> program works well. >> >> Does anyone help me? >> Looking forward to your replies. >> >> Thanks, >> Fang >> >> Below is my code. >> >> on_accept(){ >> ... >> evutil_make_socket_nonblocking(client_fd); >> >> if (num_dist==0) { >> evbase=event_base_new(); >> } >> /* Create a buffer event. */ >> bev = malloc(sizeof(struct bufferevent)); >> bev = bufferevent_socket_new(evbase, client_fd, BEV_OPT_CLOSE_ON_FREE); >> >> bufferevent_setcb(bev, buffered_on_read, buffered_on_write, NULL, NULL); >> >> bufferevent_enable(bev, EV_READ|EV_WRITE|EV_PERSIST); >> >> num_dist++; >> if (num_dist==10) { >> tid=malloc(sizeof(pthread_t)); >> pthread_mutex_lock(&mutex); >> total_thread++; >> printf("%d thread creates.\n",total_thread); >> pthread_mutex_unlock(&mutex); >> pthread_create(&tid, NULL, &server_job_function, (void *) evbase); >> num_dist=0; >> } >> >> } >> > >
