Skip to content

Commit 498708c

Browse files
committed
Merge branch 'maint'
2 parents a1c4a94 + 6ddce79 commit 498708c

6 files changed

Lines changed: 50 additions & 38 deletions

File tree

erts/emulator/beam/erl_driver.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -173,19 +173,22 @@ typedef enum {
173173
/*
174174
* Exception code from open_port/2 will be {'EXIT',{einval,Where}}.
175175
*/
176-
#define ERL_DRV_ERROR_GENERAL ((ErlDrvData) -1)
176+
#define ERL_DRV_ERROR_GENERAL_INT_ -1
177+
#define ERL_DRV_ERROR_GENERAL ((ErlDrvData) ERL_DRV_ERROR_GENERAL_INT_)
177178

178179
/*
179180
* Exception code from open_port/2 will be {'EXIT',{Errno,Where}},
180181
* where Errno is a textual representation of the errno variable
181182
* (e.g. eacces if errno is EACCES).
182183
*/
183-
#define ERL_DRV_ERROR_ERRNO ((ErlDrvData) -2)
184+
#define ERL_DRV_ERROR_ERRNO_INT_ -2
185+
#define ERL_DRV_ERROR_ERRNO ((ErlDrvData) ERL_DRV_ERROR_ERRNO_INT_)
184186

185187
/*
186188
* Exception code from open_port/2 will be {'EXIT',{badarg,Where}}.
187189
*/
188-
#define ERL_DRV_ERROR_BADARG ((ErlDrvData) -3)
190+
#define ERL_DRV_ERROR_BADARG_INT_ -3
191+
#define ERL_DRV_ERROR_BADARG ((ErlDrvData) ERL_DRV_ERROR_BADARG_INT_)
189192

190193
typedef struct erl_io_vec {
191194
int vsize; /* length of vectors */

erts/emulator/beam/erl_process.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3267,7 +3267,7 @@ aux_thread(void *vix)
32673267
if (flgs & ERTS_SSI_FLG_SLEEPING) {
32683268
ASSERT(flgs & ERTS_SSI_FLG_POLL_SLEEPING);
32693269
ASSERT(flgs & ERTS_SSI_FLG_WAITING);
3270-
erts_check_io(ssi->psi, ERTS_POLL_INF_TIMEOUT, 0);
3270+
erts_check_io(ssi->psi, ERTS_POLL_INF_TIMEOUT, false);
32713271
}
32723272
}
32733273
}
@@ -3369,7 +3369,7 @@ poll_thread(void *vbpt)
33693369

33703370
while (1) {
33713371
erts_check_io_interrupt(psi, 0);
3372-
erts_check_io(psi, ERTS_POLL_INF_TIMEOUT, !0);
3372+
erts_check_io(psi, ERTS_POLL_INF_TIMEOUT, true);
33733373
}
33743374
return NULL;
33753375
}
@@ -3564,7 +3564,7 @@ scheduler_wait(int *fcalls, ErtsSchedulerData *esdp, ErtsRunQueue *rq)
35643564
if (flgs & ERTS_SSI_FLG_SLEEPING) {
35653565
ASSERT(flgs & ERTS_SSI_FLG_POLL_SLEEPING);
35663566
ASSERT(flgs & ERTS_SSI_FLG_WAITING);
3567-
erts_check_io(ssi->psi, timeout_time, 0);
3567+
erts_check_io(ssi->psi, timeout_time, false);
35683568
current_time = erts_get_monotonic_time(esdp);
35693569
}
35703570
}
@@ -9957,7 +9957,7 @@ Process *erts_schedule(ErtsSchedulerData *esdp, Process *p, int calls)
99579957

99589958
ERTS_MSACC_SET_STATE_CACHED_M(ERTS_MSACC_STATE_CHECK_IO);
99599959

9960-
erts_check_io(esdp->ssi->psi, ERTS_POLL_NO_TIMEOUT, 0);
9960+
erts_check_io(esdp->ssi->psi, ERTS_POLL_NO_TIMEOUT, false);
99619961
ERTS_MSACC_POP_STATE_M();
99629962

99639963
current_time = erts_get_monotonic_time(esdp);

erts/emulator/beam/io.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2932,16 +2932,16 @@ erl_drv_init_ack(ErlDrvPort ix, ErlDrvData res) {
29322932

29332933
if (port->async_open_port) {
29342934
switch(err_type) {
2935-
case -3:
2935+
case ERL_DRV_ERROR_BADARG_INT_:
29362936
resp = am_badarg;
29372937
break;
2938-
case -2: {
2938+
case ERL_DRV_ERROR_ERRNO_INT_: {
29392939
char *str = erl_errno_id(errno);
29402940
resp = erts_atom_put((byte *) str, sys_strlen(str),
29412941
ERTS_ATOM_ENC_LATIN1, 1);
29422942
break;
29432943
}
2944-
case -1:
2944+
case ERL_DRV_ERROR_GENERAL_INT_:
29452945
resp = am_einval;
29462946
break;
29472947
default:
@@ -2951,7 +2951,9 @@ erl_drv_init_ack(ErlDrvPort ix, ErlDrvData res) {
29512951

29522952
init_ack_send_reply(port, resp);
29532953

2954-
if (err_type == -1 || err_type == -2 || err_type == -3)
2954+
if (res == ERL_DRV_ERROR_BADARG ||
2955+
res == ERL_DRV_ERROR_ERRNO ||
2956+
res == ERL_DRV_ERROR_GENERAL)
29552957
driver_failure_term(ix, am_normal, 0);
29562958
port->drv_data = err_type;
29572959
}

erts/emulator/sys/common/erl_check_io.c

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ typedef enum {
9595
ERTS_EV_FLAG_IN_SCHEDULER = ERTS_EV_FLAG_CLEAR,
9696
ERTS_EV_FLAG_NIF_SELECT = ERTS_EV_FLAG_CLEAR,
9797
#endif
98-
#ifdef ERTS_POLL_USE_FALLBACK
98+
#ifdef ERTS_POLL_USE_FALLBACK /* This has to be an ifdef */
9999
ERTS_EV_FLAG_FALLBACK = 0x10, /* Set when kernel poll rejected fd
100100
and it was put in the nkp version */
101101
#else
@@ -1930,10 +1930,13 @@ erts_create_pollset_thread(int id, ErtsThrPrgrData *tpd) {
19301930
}
19311931

19321932
void
1933-
erts_check_io(ErtsPollThread *psi, ErtsMonotonicTime timeout_time, int poll_only_thread)
1933+
erts_check_io(ErtsPollThread *psi, ErtsMonotonicTime timeout_time, bool needs_thread_progress)
19341934
{
19351935
int pollres_len;
19361936
int poll_ret, i;
1937+
#if ERTS_POLL_USE_SCHEDULER_POLLING
1938+
bool is_scheduler_poll = psi->ps == get_scheduler_pollset();
1939+
#endif
19371940
ERTS_MSACC_PUSH_AND_SET_STATE(ERTS_MSACC_STATE_CHECK_IO);
19381941

19391942
restart:
@@ -1944,7 +1947,7 @@ erts_check_io(ErtsPollThread *psi, ErtsMonotonicTime timeout_time, int poll_only
19441947

19451948
pollres_len = psi->pollres_len;
19461949

1947-
if (poll_only_thread)
1950+
if (needs_thread_progress)
19481951
erts_thr_progress_active(psi->tpd, 0);
19491952

19501953
#if ERTS_POLL_USE_FALLBACK
@@ -1958,7 +1961,7 @@ erts_check_io(ErtsPollThread *psi, ErtsMonotonicTime timeout_time, int poll_only
19581961
poll_ret = erts_poll_wait(psi->ps, psi->pollres, &pollres_len, psi->tpd, timeout_time);
19591962
}
19601963

1961-
if (poll_only_thread)
1964+
if (needs_thread_progress)
19621965
erts_thr_progress_active(psi->tpd, 1);
19631966

19641967
#ifdef ERTS_ENABLE_LOCK_CHECK
@@ -1982,9 +1985,6 @@ erts_check_io(ErtsPollThread *psi, ErtsMonotonicTime timeout_time, int poll_only
19821985
erl_errno_id(poll_ret), poll_ret);
19831986
erts_send_error_to_logger_nogl(dsbufp);
19841987
}
1985-
// if (is_normal_sched) {
1986-
// erts_fprintf(stderr, "%d: woke up\r\n", esdp->no);
1987-
// }
19881988
ERTS_MSACC_POP_STATE();
19891989
return;
19901990
}
@@ -2028,13 +2028,18 @@ erts_check_io(ErtsPollThread *psi, ErtsMonotonicTime timeout_time, int poll_only
20282028

20292029
#if ERTS_POLL_USE_SCHEDULER_POLLING
20302030
if (state->flags & ERTS_EV_FLAG_SCHEDULER) {
2031-
/* In the poll thread, this fd would have been disabled due to ONESHOT,
2032-
but in the scheduler pollset it needs to be disabled manually. */
2033-
int wake_poller = 0;
2034-
erts_poll_control(get_scheduler_pollset(), fd, ERTS_POLL_OP_DEL, 0, &wake_poller);
2035-
state->flags &= ~(ERTS_EV_FLAG_SCHEDULER|ERTS_EV_FLAG_IN_SCHEDULER);
2036-
state->count = 0;
2037-
state->last_select_pid = NIL;
2031+
if (is_scheduler_poll) {
2032+
/* If we triggered in a scheduler pollset,
2033+
then we should just remove it from the
2034+
scheduler pollset. */
2035+
int wake_poller = 0;
2036+
erts_poll_control(psi->ps, fd, ERTS_POLL_OP_DEL, 0, &wake_poller);
2037+
state->flags &= ~(ERTS_EV_FLAG_SCHEDULER|ERTS_EV_FLAG_IN_SCHEDULER);
2038+
state->count = 0;
2039+
state->last_select_pid = NIL;
2040+
} else {
2041+
state->active_events = revents & ERTS_POLL_EV_IN;
2042+
}
20382043
}
20392044
#endif
20402045
} else {
@@ -2045,7 +2050,7 @@ erts_check_io(ErtsPollThread *psi, ErtsMonotonicTime timeout_time, int poll_only
20452050
revents &= state->active_events | ERTS_POLL_EV_NVAL;
20462051

20472052
#if ERTS_POLL_USE_SCHEDULER_POLLING
2048-
if (psi->ps == get_scheduler_pollset()) {
2053+
if (is_scheduler_poll) {
20492054
if (!(state->events & ERTS_POLL_EV_IN) && state->flags & ERTS_EV_FLAG_SCHEDULER) {
20502055
/* If we triggered in a scheduler pollset and EV_IN is not set,
20512056
then we should just remove it from the scheduler pollset.
@@ -2176,7 +2181,7 @@ erts_check_io(ErtsPollThread *psi, ErtsMonotonicTime timeout_time, int poll_only
21762181

21772182
case ERTS_EV_TYPE_STOP_NIF: {
21782183
#if ERTS_POLL_USE_SCHEDULER_POLLING
2179-
if (psi->ps == get_scheduler_pollset())
2184+
if (is_scheduler_poll)
21802185
break;
21812186
#endif
21822187
#if ERTS_POLL_USE_FALLBACK
@@ -2189,7 +2194,7 @@ erts_check_io(ErtsPollThread *psi, ErtsMonotonicTime timeout_time, int poll_only
21892194

21902195
case ERTS_EV_TYPE_STOP_USE: {
21912196
#if ERTS_POLL_USE_SCHEDULER_POLLING
2192-
if (psi->ps == get_scheduler_pollset())
2197+
if (is_scheduler_poll)
21932198
break;
21942199
#endif
21952200
#if ERTS_POLL_USE_FALLBACK

erts/emulator/sys/common/erl_check_io.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,11 +87,11 @@ int erts_check_io_max_files(void);
8787
*
8888
* @param pt the poll thread structure to use.
8989
* @param timeout_time timeout
90-
* @param poll_only_thread non zero when poll is the only thing the
91-
* calling thread does
90+
* @param needs_thread_progress true when the calling thread needs to have its
91+
* thread progress managed, false otherwise.
9292
*/
9393
void erts_check_io(struct erts_poll_thread *pt, ErtsMonotonicTime timeout_time,
94-
int poll_only_thread);
94+
bool needs_thread_progress);
9595
/**
9696
* Initialize the check io framework. This function will parse the arguments
9797
* and delete any entries that it is interested in.

erts/emulator/sys/unix/sys_drivers.c

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -743,12 +743,15 @@ static ErlDrvSSizeT spawn_control(ErlDrvData e, unsigned int cmd, char *buf,
743743
dd->status = proto->u.sigchld.error_number;
744744
dd->alive = -1;
745745

746-
if (dd->ifd)
747-
driver_select(dd->port_num, abs(dd->ifd->fd), ERL_DRV_READ | ERL_DRV_USE, 1);
748-
749746
if (dd->ofd)
750747
driver_select(dd->port_num, abs(dd->ofd->fd), ERL_DRV_WRITE | ERL_DRV_USE, 1);
751748

749+
/* We call ready_input directly as not all OSs trigger an input event on an
750+
fd that already triggered EOF. For example ONESHOT poll on Linux and FreeBSD will not. */
751+
if (dd->ifd) {
752+
ready_input(e, abs(dd->ifd->fd));
753+
}
754+
752755
return 0;
753756
}
754757

@@ -1230,9 +1233,9 @@ static int port_inp_failure(ErtsSysDriverData *dd, int res)
12301233
if (dd->alive == 1) {
12311234
/*
12321235
* We have eof and want to report exit status, but the process
1233-
* hasn't exited yet. When it does ready_input will
1234-
* driver_select() this fd which will make sure that we get
1235-
* back here with dd->alive == -1 and dd->status set.
1236+
* hasn't exited yet. When it does spawn_control will call ready_input
1237+
* which will make sure that we get back here with dd->alive == -1 and
1238+
* dd->status set.
12361239
*/
12371240
return 0;
12381241
}
@@ -1284,7 +1287,6 @@ static void ready_input(ErlDrvData e, ErlDrvEvent ready_fd)
12841287
return;
12851288
/* hmm, child setup seems to have closed the pipe too early...
12861289
we close the port as there is not much else we can do */
1287-
driver_select(port_num, ready_fd, ERL_DRV_READ, 0);
12881290
if (res == 0)
12891291
errno = EPIPE;
12901292
port_inp_failure(dd, -1);

0 commit comments

Comments
 (0)