Skip to content

Commit 14a0d65

Browse files
committed
Merge from #5 @xiaosuo
2 parents 7a74a6a + 50912bf commit 14a0d65

File tree

4 files changed

+154
-42
lines changed

4 files changed

+154
-42
lines changed

README.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
state-threads
2-
=============
32

43
Fork from http://sourceforge.net/projects/state-threads, patched for [SRS](https://github.com/ossrs/srs/tree/2.0release).
54

common.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,8 @@ typedef struct _st_eventsys_ops {
228228
int (*fd_new)(int); /* New descriptor allocated */
229229
int (*fd_close)(int); /* Descriptor closed */
230230
int (*fd_getlimit)(void); /* Descriptor hard limit */
231+
int (*pollq_add)(_st_pollq_t *pq);
232+
void (*pollq_del)(_st_pollq_t *pq);
231233
} _st_eventsys_t;
232234

233235

event.c

Lines changed: 148 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,12 @@ typedef struct _epoll_fd_data {
119119
int wr_ref_cnt;
120120
int ex_ref_cnt;
121121
int revents;
122+
/* The following members aren't touched after forking. */
123+
union {
124+
_st_pollq_t *pq;
125+
_st_pollq_t **pqs;
126+
};
127+
int pq_cnt;
122128
} _epoll_fd_data_t;
123129

124130
static struct _st_epolldata {
@@ -1194,16 +1200,97 @@ ST_HIDDEN int _st_epoll_pollset_add(struct pollfd *pds, int npds)
11941200
return 0;
11951201
}
11961202

1203+
ST_HIDDEN void _st_epoll_pollq_del(_st_pollq_t *pq)
1204+
{
1205+
struct pollfd *pd = pq->pds;
1206+
struct pollfd *pd_end = pd + pq->npds;
1207+
_epoll_fd_data_t *efd;
1208+
int i;
1209+
1210+
while (pd < pd_end) {
1211+
efd = &_st_epoll_data->fd_data[pd->fd];
1212+
if (efd->pq_cnt == 1) {
1213+
if (efd->pq == pq)
1214+
efd->pq = NULL;
1215+
} else if (efd->pq_cnt > 0) {
1216+
for (i = 0; i < efd->pq_cnt; ++i) {
1217+
if (efd->pqs[i] == pq) {
1218+
efd->pqs[i] = NULL;
1219+
break;
1220+
}
1221+
}
1222+
}
1223+
++pd;
1224+
}
1225+
}
1226+
1227+
ST_HIDDEN int _st_epoll_pollq_add(_st_pollq_t *pq)
1228+
{
1229+
struct pollfd *pd = pq->pds;
1230+
struct pollfd *pd_end = pd + pq->npds;
1231+
_epoll_fd_data_t *efd;
1232+
int i;
1233+
_st_pollq_t **pqs;
1234+
1235+
while (pd < pd_end) {
1236+
efd = &_st_epoll_data->fd_data[pd->fd];
1237+
if (efd->pq_cnt == 0) {
1238+
efd->pq = pq;
1239+
efd->pq_cnt = 1;
1240+
} else if (efd->pq_cnt == 1) {
1241+
if (efd->pq == NULL) {
1242+
efd->pq = pq;
1243+
} else {
1244+
assert(efd->pq != pq);
1245+
pqs = malloc(sizeof(*pqs) * 2);
1246+
if (!pqs) {
1247+
_st_epoll_pollq_del(pq);
1248+
errno = ENOMEM;
1249+
return -1;
1250+
}
1251+
pqs[0] = efd->pq;
1252+
pqs[1] = pq;
1253+
efd->pqs = pqs;
1254+
efd->pq_cnt = 2;
1255+
}
1256+
} else {
1257+
for (i = 0; i < efd->pq_cnt; ++i) {
1258+
if (efd->pqs[i] == NULL) {
1259+
efd->pqs[i] = pq;
1260+
break;
1261+
} else {
1262+
assert(efd->pqs[i] != pq);
1263+
}
1264+
}
1265+
if (i == efd->pq_cnt) {
1266+
pqs = realloc(efd->pqs, sizeof(*pqs) * (efd->pq_cnt + 1));
1267+
if (!pqs) {
1268+
_st_epoll_pollq_del(pq);
1269+
errno = ENOMEM;
1270+
return -1;
1271+
}
1272+
efd->pqs = pqs;
1273+
efd->pqs[efd->pq_cnt++] = pq;
1274+
}
1275+
}
1276+
++pd;
1277+
}
1278+
1279+
return 0;
1280+
}
1281+
11971282
ST_HIDDEN void _st_epoll_dispatch(void)
11981283
{
11991284
st_utime_t min_timeout;
12001285
_st_clist_t *q;
12011286
_st_pollq_t *pq;
12021287
struct pollfd *pds, *epds;
12031288
struct epoll_event ev;
1204-
int timeout, nfd, i, osfd, notify;
1289+
int timeout, nfd, i, j, osfd, notify;
12051290
int events, op;
12061291
short revents;
1292+
_epoll_fd_data_t *efd;
1293+
_st_pollq_t **pqs;
12071294

12081295
if (_ST_SLEEPQ == NULL) {
12091296
timeout = -1;
@@ -1224,7 +1311,10 @@ ST_HIDDEN void _st_epoll_dispatch(void)
12241311
_st_epoll_data->pid = getpid();
12251312

12261313
/* Put all descriptors on ioq into new epoll set */
1227-
memset(_st_epoll_data->fd_data, 0, _st_epoll_data->fd_data_size * sizeof(_epoll_fd_data_t));
1314+
for (i = 0; i < _st_epoll_data->fd_data_size; ++i) {
1315+
memset(&_st_epoll_data->fd_data[i], 0,
1316+
offsetof(_epoll_fd_data_t, pq));
1317+
}
12281318
_st_epoll_data->evtlist_cnt = 0;
12291319
for (q = _ST_IOQ.next; q != &_ST_IOQ; q = q->next) {
12301320
pq = _ST_POLLQUEUE_PTR(q);
@@ -1245,48 +1335,63 @@ ST_HIDDEN void _st_epoll_dispatch(void)
12451335
}
12461336
}
12471337

1248-
for (q = _ST_IOQ.next; q != &_ST_IOQ; q = q->next) {
1249-
pq = _ST_POLLQUEUE_PTR(q);
1250-
notify = 0;
1251-
epds = pq->pds + pq->npds;
1252-
1253-
for (pds = pq->pds; pds < epds; pds++) {
1254-
if (_ST_EPOLL_REVENTS(pds->fd) == 0) {
1255-
pds->revents = 0;
1338+
for (i = 0; i < nfd; ++i) {
1339+
osfd = _st_epoll_data->evtlist[i].data.fd;
1340+
efd = &_st_epoll_data->fd_data[osfd];
1341+
assert(efd->pq_cnt > 0);
1342+
if (efd->pq_cnt == 1)
1343+
pqs = &efd->pq;
1344+
else
1345+
pqs = efd->pqs;
1346+
for (j = 0; j < efd->pq_cnt; ++j) {
1347+
pq = pqs[j];
1348+
if (!pq)
12561349
continue;
1257-
}
1258-
osfd = pds->fd;
1259-
events = pds->events;
1260-
revents = 0;
1261-
if ((events & POLLIN) && (_ST_EPOLL_REVENTS(osfd) & EPOLLIN))
1262-
revents |= POLLIN;
1263-
if ((events & POLLOUT) && (_ST_EPOLL_REVENTS(osfd) & EPOLLOUT))
1264-
revents |= POLLOUT;
1265-
if ((events & POLLPRI) && (_ST_EPOLL_REVENTS(osfd) & EPOLLPRI))
1266-
revents |= POLLPRI;
1267-
if (_ST_EPOLL_REVENTS(osfd) & EPOLLERR)
1268-
revents |= POLLERR;
1269-
if (_ST_EPOLL_REVENTS(osfd) & EPOLLHUP)
1270-
revents |= POLLHUP;
1350+
notify = 0;
1351+
epds = pq->pds + pq->npds;
12711352

1272-
pds->revents = revents;
1273-
if (revents) {
1274-
notify = 1;
1353+
for (pds = pq->pds; pds < epds; pds++) {
1354+
if (_ST_EPOLL_REVENTS(pds->fd) == 0) {
1355+
pds->revents = 0;
1356+
continue;
1357+
}
1358+
osfd = pds->fd;
1359+
events = pds->events;
1360+
revents = 0;
1361+
if ((events & POLLIN) &&
1362+
(_ST_EPOLL_REVENTS(osfd) & EPOLLIN))
1363+
revents |= POLLIN;
1364+
if ((events & POLLOUT) &&
1365+
(_ST_EPOLL_REVENTS(osfd) & EPOLLOUT))
1366+
revents |= POLLOUT;
1367+
if ((events & POLLPRI) &&
1368+
(_ST_EPOLL_REVENTS(osfd) & EPOLLPRI))
1369+
revents |= POLLPRI;
1370+
if (_ST_EPOLL_REVENTS(osfd) & EPOLLERR)
1371+
revents |= POLLERR;
1372+
if (_ST_EPOLL_REVENTS(osfd) & EPOLLHUP)
1373+
revents |= POLLHUP;
1374+
1375+
pds->revents = revents;
1376+
if (revents) {
1377+
notify = 1;
1378+
}
12751379
}
1276-
}
1277-
if (notify) {
1278-
ST_REMOVE_LINK(&pq->links);
1279-
pq->on_ioq = 0;
1280-
/*
1281-
* Here we will only delete/modify descriptors that
1282-
* didn't fire (see comments in _st_epoll_pollset_del()).
1283-
*/
1284-
_st_epoll_pollset_del(pq->pds, pq->npds);
1380+
if (notify) {
1381+
_st_epoll_pollq_del(pq);
1382+
ST_REMOVE_LINK(&pq->links);
1383+
pq->on_ioq = 0;
1384+
/*
1385+
* Here we will only delete/modify descriptors that
1386+
* didn't fire (see comments in _st_epoll_pollset_del()).
1387+
*/
1388+
_st_epoll_pollset_del(pq->pds, pq->npds);
12851389

1286-
if (pq->thread->flags & _ST_FL_ON_SLEEPQ)
1287-
_ST_DEL_SLEEPQ(pq->thread);
1288-
pq->thread->state = _ST_ST_RUNNABLE;
1289-
_ST_ADD_RUNQ(pq->thread);
1390+
if (pq->thread->flags & _ST_FL_ON_SLEEPQ)
1391+
_ST_DEL_SLEEPQ(pq->thread);
1392+
pq->thread->state = _ST_ST_RUNNABLE;
1393+
_ST_ADD_RUNQ(pq->thread);
1394+
}
12901395
}
12911396
}
12921397

@@ -1353,7 +1458,9 @@ static _st_eventsys_t _st_epoll_eventsys = {
13531458
_st_epoll_pollset_del,
13541459
_st_epoll_fd_new,
13551460
_st_epoll_fd_close,
1356-
_st_epoll_fd_getlimit
1461+
_st_epoll_fd_getlimit,
1462+
_st_epoll_pollq_add,
1463+
_st_epoll_pollq_del
13571464
};
13581465
#endif /* MD_HAVE_EPOLL */
13591466

sched.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,8 @@ int st_poll(struct pollfd *pds, int npds, st_utime_t timeout)
8383
pq.npds = npds;
8484
pq.thread = me;
8585
pq.on_ioq = 1;
86+
if (*_st_eventsys->pollq_add && (*_st_eventsys->pollq_add)(&pq))
87+
return -1;
8688
_ST_ADD_IOQ(pq);
8789
if (timeout != ST_UTIME_NO_TIMEOUT)
8890
_ST_ADD_SLEEPQ(me, timeout);
@@ -92,6 +94,8 @@ int st_poll(struct pollfd *pds, int npds, st_utime_t timeout)
9294

9395
n = 0;
9496
if (pq.on_ioq) {
97+
if (*_st_eventsys->pollq_del)
98+
(*_st_eventsys->pollq_del)(&pq);
9599
/* If we timed out, the pollq might still be on the ioq. Remove it */
96100
_ST_DEL_IOQ(pq);
97101
(*_st_eventsys->pollset_del)(pds, npds);

0 commit comments

Comments
 (0)