Only do one event at a time to a callback.
This commit is contained in:
@@ -42,10 +42,11 @@ struct IOMux;
|
|||||||
struct IOMuxFD;
|
struct IOMuxFD;
|
||||||
|
|
||||||
/** Callback function used in struct IOMuxFD
|
/** Callback function used in struct IOMuxFD
|
||||||
|
*
|
||||||
* @param mux the mux that issued the callback.
|
* @param mux the mux that issued the callback.
|
||||||
* @param fd the file desciptor structure.
|
* @param fd the file desciptor structure.
|
||||||
* @param event A bitmask of the MUX_EV_XX values. Both a read and a write event
|
* @param event A bitmask of the MUX_EV_XX values. Only one event(bit)
|
||||||
* might be signalled in the same callback
|
* will be signalled in the same callback
|
||||||
*/
|
*/
|
||||||
typedef void (*iomux_cb)(struct IOMux *mux, struct IOMuxFD *fd, unsigned int event);
|
typedef void (*iomux_cb)(struct IOMux *mux, struct IOMuxFD *fd, unsigned int event);
|
||||||
|
|
||||||
|
|||||||
+19
-10
@@ -162,7 +162,7 @@ static int iomux_epoll_run(struct IOMux *mux_, struct timeval *timeout)
|
|||||||
|
|
||||||
rc = epoll_wait(mux->epoll_fd, mux->pending_events, EPOLL_WAIT_EVENTS, timeout_ms);
|
rc = epoll_wait(mux->epoll_fd, mux->pending_events, EPOLL_WAIT_EVENTS, timeout_ms);
|
||||||
|
|
||||||
while (rc == -1 && errno == EINTR)
|
} while (rc == -1 && errno == EINTR);
|
||||||
|
|
||||||
assert(rc >= 0);
|
assert(rc >= 0);
|
||||||
if(rc < 0)
|
if(rc < 0)
|
||||||
@@ -177,18 +177,27 @@ static int iomux_epoll_run(struct IOMux *mux_, struct timeval *timeout)
|
|||||||
|
|
||||||
for (i = 0; i < rc; i++) {
|
for (i = 0; i < rc; i++) {
|
||||||
struct IOMuxFD *fd = mux->pending_events[i].data.ptr;
|
struct IOMuxFD *fd = mux->pending_events[i].data.ptr;
|
||||||
if (fd != NULL) { //calling _unregister from a callback could have removed it
|
unsigned int events;
|
||||||
unsigned int events;
|
|
||||||
|
|
||||||
events = epoll_2_mux_events(mux->pending_events[i].events);
|
events = epoll_2_mux_events(mux->pending_events[i].events);
|
||||||
|
|
||||||
|
//we want to deliver only one event at a time to simplify
|
||||||
|
//application programming.
|
||||||
|
fd = mux->pending_events[i].data.ptr;
|
||||||
|
|
||||||
|
if (events & MUX_EV_READ && fd != NULL) {
|
||||||
assert(fd->callback != NULL);
|
assert(fd->callback != NULL);
|
||||||
fd->callback(mux_, fd, events);
|
fd->callback(mux_, fd, MUX_EV_READ);
|
||||||
//be sure not to use fd after the callback, it might been removed.
|
|
||||||
|
|
||||||
mux->pending_events[i].data.ptr = NULL; //clear from pending list
|
|
||||||
|
|
||||||
event_cnt++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//now re-check, in case the IOMuxFD was removed
|
||||||
|
fd = mux->pending_events[i].data.ptr;
|
||||||
|
if (events & MUX_EV_WRITE && fd != NULL) {
|
||||||
|
assert(fd->callback != NULL);
|
||||||
|
fd->callback(mux_, fd, MUX_EV_WRITE);
|
||||||
|
}
|
||||||
|
|
||||||
|
event_cnt += events != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
mux->pending = 0;
|
mux->pending = 0;
|
||||||
|
|||||||
+18
-17
@@ -150,7 +150,7 @@ static int iomux_select_run(struct IOMux *mux_, struct timeval *timeout)
|
|||||||
write_set = mux->master_write_set;
|
write_set = mux->master_write_set;
|
||||||
rc = select(mux->max_fd + 1, &read_set, &write_set, NULL, timeout); //we can use timeout directly
|
rc = select(mux->max_fd + 1, &read_set, &write_set, NULL, timeout); //we can use timeout directly
|
||||||
|
|
||||||
while (rc == -1 && errno == EINTR)
|
} while (rc == -1 && errno == EINTR);
|
||||||
|
|
||||||
assert(rc >= 0);
|
assert(rc >= 0);
|
||||||
if (rc < 0)
|
if (rc < 0)
|
||||||
@@ -164,25 +164,26 @@ static int iomux_select_run(struct IOMux *mux_, struct timeval *timeout)
|
|||||||
for (i = 0; rc > 0 && i < mux->num_descriptors; i++) {
|
for (i = 0; rc > 0 && i < mux->num_descriptors; i++) {
|
||||||
unsigned int events = 0;
|
unsigned int events = 0;
|
||||||
|
|
||||||
if (mux->descriptors[i] == NULL) { //callback might have deleted it
|
//deliver only one event at a time , to simplify application
|
||||||
continue;
|
//programming
|
||||||
}
|
if (mux->descriptors[i] != NULL &&
|
||||||
|
FD_ISSET(mux->descriptors[i]->fd, &read_set)) {
|
||||||
if (FD_ISSET(mux->descriptors[i]->fd, &read_set)) {
|
|
||||||
rc--;
|
rc--;
|
||||||
events |= MUX_EV_READ;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (FD_ISSET(mux->descriptors[i]->fd, &write_set)) {
|
|
||||||
rc--;
|
|
||||||
events |= MUX_EV_WRITE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (events) {
|
|
||||||
assert(mux->descriptors[i]->callback != NULL);
|
assert(mux->descriptors[i]->callback != NULL);
|
||||||
mux->descriptors[i]->callback(mux_, mux->descriptors[i], events);
|
mux->descriptors[i]->callback(mux_, mux->descriptors[i], MUX_EV_READ);
|
||||||
event_cnt++;
|
events = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//need to re-check in case the callback deleted the IOMuxFD
|
||||||
|
if (mux->descriptors[i] != NULL &&
|
||||||
|
FD_ISSET(mux->descriptors[i]->fd, &write_set)) {
|
||||||
|
rc--;
|
||||||
|
assert(mux->descriptors[i]->callback != NULL);
|
||||||
|
mux->descriptors[i]->callback(mux_, mux->descriptors[i], MUX_EV_WRITE);
|
||||||
|
events = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
event_cnt += events;
|
||||||
}
|
}
|
||||||
|
|
||||||
return event_cnt;
|
return event_cnt;
|
||||||
|
|||||||
Reference in New Issue
Block a user