aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator
diff options
context:
space:
mode:
Diffstat (limited to 'erts/emulator')
-rw-r--r--erts/emulator/beam/erl_driver.h21
-rwxr-xr-xerts/emulator/beam/global.h3
-rw-r--r--erts/emulator/beam/io.c3
-rw-r--r--erts/emulator/drivers/ose/ose_signal_drv.c41
-rw-r--r--erts/emulator/sys/common/erl_check_io.c99
-rw-r--r--erts/emulator/sys/common/erl_poll.h20
-rw-r--r--erts/emulator/sys/ose/erl_ose_sys.h14
-rw-r--r--erts/emulator/sys/ose/erl_poll.c116
-rw-r--r--erts/emulator/sys/ose/sys.c49
9 files changed, 158 insertions, 208 deletions
diff --git a/erts/emulator/beam/erl_driver.h b/erts/emulator/beam/erl_driver.h
index 9ede2982de..a15b0e17f5 100644
--- a/erts/emulator/beam/erl_driver.h
+++ b/erts/emulator/beam/erl_driver.h
@@ -272,14 +272,6 @@ typedef struct ErlDrvRWLock_ ErlDrvRWLock;
typedef int ErlDrvTSDKey;
/*
- * Potential OSE signals
- */
-#ifdef __OSE__
-typedef union SIGNAL OseSignal;
-#endif
-
-
-/*
*
*/
typedef struct erl_drv_port_data_lock * ErlDrvPDL;
@@ -353,9 +345,6 @@ typedef struct erl_drv_entry {
/* Called on behalf of driver_select when
it is safe to release 'event'. A typical
unix driver would call close(event) */
-#ifdef __OSE__
- int (*resolve_signal)(OseSignal* sig, int* mode);
-#endif
/* When adding entries here, dont forget to pad in obsolete/driver.h */
} ErlDrvEntry;
@@ -691,11 +680,13 @@ EXTERN int erl_drv_putenv(char *key, char *value);
EXTERN int erl_drv_getenv(char *key, char *value, size_t *value_size);
#ifdef __OSE__
-EXTERN OseSignal *erl_drv_ose_get_output_signal(ErlDrvEvent ev);
-EXTERN OseSignal *erl_drv_ose_get_input_signal(ErlDrvEvent ev);
-EXTERN ErlDrvEvent erl_drv_ose_event_alloc(SIGSELECT sig,int id);
+typedef ErlDrvUInt ErlDrvOseEventId;
+EXTERN union SIGNAL *erl_drv_ose_get_signal(ErlDrvEvent ev);
+EXTERN ErlDrvEvent erl_drv_ose_event_alloc(SIGSELECT sig,ErlDrvOseEventId id,
+ ErlDrvOseEventId (*resolve_signal)(union SIGNAL *sig));
EXTERN void erl_drv_ose_event_free(ErlDrvEvent ev);
-EXTERN void erl_drv_ose_event_fetch(ErlDrvEvent ev, SIGSELECT *sig,int *id);
+EXTERN void erl_drv_ose_event_fetch(ErlDrvEvent ev, SIGSELECT *sig,
+ ErlDrvOseEventId *id);
#endif
#endif /* !ERL_DRIVER_TYPES_ONLY */
diff --git a/erts/emulator/beam/global.h b/erts/emulator/beam/global.h
index 5a97ac5892..8fcb95d0e2 100755
--- a/erts/emulator/beam/global.h
+++ b/erts/emulator/beam/global.h
@@ -160,9 +160,6 @@ struct erts_driver_t_ {
void (*ready_async)(ErlDrvData drv_data, ErlDrvThreadData thread_data); /* Might be NULL */
void (*process_exit)(ErlDrvData drv_data, ErlDrvMonitor *monitor);
void (*stop_select)(ErlDrvEvent event, void*); /* Might be NULL */
-#ifdef __OSE__
- int (*resolve_signal)(OseSignal* sig, int* mode);
-#endif
};
extern erts_driver_t *driver_list;
diff --git a/erts/emulator/beam/io.c b/erts/emulator/beam/io.c
index 09681f167d..cd5060ebb3 100644
--- a/erts/emulator/beam/io.c
+++ b/erts/emulator/beam/io.c
@@ -7342,9 +7342,6 @@ init_driver(erts_driver_t *drv, ErlDrvEntry *de, DE_Handle *handle)
drv->stop_select = de->stop_select;
else
drv->stop_select = no_stop_select_callback;
-#ifdef __OSE__
- drv->resolve_signal = de->resolve_signal;
-#endif
if (!de->init)
return 0;
diff --git a/erts/emulator/drivers/ose/ose_signal_drv.c b/erts/emulator/drivers/ose/ose_signal_drv.c
index c1d861cc5a..46890a1503 100644
--- a/erts/emulator/drivers/ose/ose_signal_drv.c
+++ b/erts/emulator/drivers/ose/ose_signal_drv.c
@@ -392,6 +392,19 @@ static int drv_init(void) {
return 0;
}
+/* Signal resolution callback */
+static ErlDrvOseEventId resolve_signal(union SIGNAL* osig) {
+ union SIGNAL *sig = osig;
+ if (sig->signo == ERTS_SIGNAL_OSE_DRV_HUNT ||
+ sig->signo == ERTS_SIGNAL_OSE_DRV_ATTACH) {
+ return sig->async.spid;
+ }
+ DEBUGP("%p: Got signal %d sent to %p from 0x%p\n",
+ current_process(),sig->signo,addressee(&sig),sender(&sig));
+ return addressee(&sig);
+}
+
+
/**
* Start routine for the driver
**/
@@ -488,11 +501,13 @@ static void outputv(ErlDrvData driver_data, ErlIOVec *ev)
DEBUGP("0x%x: open\n",ctxt->spid);
ctxt->perm_events[1] =
- erl_drv_ose_event_alloc(ERTS_SIGNAL_OSE_DRV_ATTACH,(int)ctxt->spid);
+ erl_drv_ose_event_alloc(ERTS_SIGNAL_OSE_DRV_ATTACH,(int)ctxt->spid,
+ resolve_signal);
driver_select(ctxt->port,ctxt->perm_events[1],ERL_DRV_READ|ERL_DRV_USE,1);
ctxt->perm_events[0] =
- erl_drv_ose_event_alloc(ERTS_SIGNAL_OSE_DRV_HUNT,(int)ctxt->spid);
+ erl_drv_ose_event_alloc(ERTS_SIGNAL_OSE_DRV_HUNT,(int)ctxt->spid,
+ resolve_signal);
driver_select(ctxt->port,ctxt->perm_events[0],ERL_DRV_READ|ERL_DRV_USE,1);
start(ctxt->spid);
@@ -669,7 +684,8 @@ static void outputv(ErlDrvData driver_data, ErlIOVec *ev)
EV_GET_UINT32(ev,&signo,&p,&q);
} else if (signo < tmp_signo || !ctxt->events) {
/* New signal to select on */
- events[i] = erl_drv_ose_event_alloc(signo,(int)ctxt->spid);
+ events[i] = erl_drv_ose_event_alloc(signo,(int)ctxt->spid,
+ resolve_signal);
driver_select(ctxt->port,events[i++],ERL_DRV_READ|ERL_DRV_USE,1);
EV_GET_UINT32(ev,&signo,&p,&q);
} else {
@@ -708,7 +724,7 @@ static void outputv(ErlDrvData driver_data, ErlIOVec *ev)
static void ready_input(ErlDrvData driver_data, ErlDrvEvent event)
{
driver_context_t *ctxt = (driver_context_t *)driver_data;
- union SIGNAL *sig = erl_drv_ose_get_input_signal(event);
+ union SIGNAL *sig = erl_drv_ose_get_signal(event);
while (sig != NULL) {
@@ -800,7 +816,7 @@ static void ready_input(ErlDrvData driver_data, ErlDrvEvent event)
}
free_buf(&sig);
- sig = erl_drv_ose_get_input_signal(event);
+ sig = erl_drv_ose_get_signal(event);
}
}
@@ -858,17 +874,6 @@ static void stop_select(ErlDrvEvent event, void *reserved)
erl_drv_ose_event_free(event);
}
-static int resolve_signal(OseSignal* osig, int *mode) {
- union SIGNAL *sig = osig;
- if (sig->signo == ERTS_SIGNAL_OSE_DRV_HUNT ||
- sig->signo == ERTS_SIGNAL_OSE_DRV_ATTACH) {
- return sig->async.spid;
- }
- DEBUGP("%p: Got signal %d sent to %p from 0x%p\n",
- current_process(),sig->signo,addressee(&sig),sender(&sig));
- return addressee(&sig);
-}
-
/**
* Setup the driver entry for the Erlang runtime
**/
@@ -884,6 +889,6 @@ ErlDrvEntry ose_signal_driver_entry = {
.major_version = ERL_DRV_EXTENDED_MAJOR_VERSION,
.minor_version = ERL_DRV_EXTENDED_MINOR_VERSION,
.driver_flags = ERL_DRV_FLAG_USE_PORT_LOCKING,
- .stop_select = stop_select,
- .resolve_signal = resolve_signal
+ .stop_select = stop_select
};
+
diff --git a/erts/emulator/sys/common/erl_check_io.c b/erts/emulator/sys/common/erl_check_io.c
index dab056e2df..245841a768 100644
--- a/erts/emulator/sys/common/erl_check_io.c
+++ b/erts/emulator/sys/common/erl_check_io.c
@@ -79,11 +79,7 @@ typedef char EventStateFlags;
#define ERTS_CIO_POLL_INIT ERTS_POLL_EXPORT(erts_poll_init)
#define ERTS_CIO_POLL_INFO ERTS_POLL_EXPORT(erts_poll_info)
-#ifdef __OSE__
-#define GET_FD(fd) fd->id
-#else
#define GET_FD(fd) fd
-#endif
static struct pollset_info
{
@@ -442,11 +438,7 @@ deselect(ErtsDrvEventState *state, int mode)
}
}
- state->events = ERTS_CIO_POLL_CTL(pollset.ps, state->fd, rm_events, 0, &do_wake
-#ifdef __OSE__
- ,NULL
-#endif
- );
+ state->events = ERTS_CIO_POLL_CTL(pollset.ps, state->fd, rm_events, 0, &do_wake);
if (!(state->events)) {
switch (state->type) {
@@ -595,11 +587,7 @@ ERTS_CIO_EXPORT(driver_select)(ErlDrvPort ix,
wake_poller = 1;
}
- new_events = ERTS_CIO_POLL_CTL(pollset.ps, state->fd, ctl_events, on, &wake_poller
-#ifdef __OSE__
- ,prt->drv_ptr->resolve_signal
-#endif
- );
+ new_events = ERTS_CIO_POLL_CTL(pollset.ps, state->fd, ctl_events, on, &wake_poller);
if (new_events & (ERTS_POLL_EV_ERR|ERTS_POLL_EV_NVAL)) {
if (state->type == ERTS_EV_TYPE_DRV_SEL && !state->events) {
@@ -984,9 +972,6 @@ print_select_op(erts_dsprintf_buf_t *dsbufp,
mode & ERL_DRV_WRITE ? " ERL_DRV_WRITE" : "",
mode & ERL_DRV_USE ? " ERL_DRV_USE" : "",
mode & (ERL_DRV_USE_NO_CALLBACK & ~ERL_DRV_USE) ? "_NO_CALLBACK" : "",
-#ifdef __OSE__
- fd->signo,
-#endif
on);
print_driver_name(dsbufp, pp != ERTS_INVALID_ERL_DRV_PORT ? pp->common.id : NIL);
erts_dsprintf(dsbufp, "driver %T ", pp != ERTS_INVALID_ERL_DRV_PORT ? pp->common.id : NIL);
@@ -1417,20 +1402,26 @@ stale_drv_select(Eterm id, ErtsDrvEventState *state, int mode)
}
#ifndef ERTS_SYS_CONTINOUS_FD_NUMBERS
+
#ifdef __OSE__
static SafeHashValue drv_ev_state_hash(void *des)
{
- SafeHashValue val = (SafeHashValue) ((ErtsDrvEventState *) des)->fd;
- return val ^ (val >> 8); /* Good enough for aligned pointer values? */
+ ErtsSysFdType fd = ((ErtsDrvEventState *) des)->fd;
+ /* We use hash on signo ^ id in order for steal to happen when the
+ same signo + fd is selected on by two different ports */
+ SafeHashValue val = (SafeHashValue)(fd->signo ^ fd->id);
+ return val ^ (val >> 8);
}
static int drv_ev_state_cmp(void *des1, void *des2)
{
- return ( ((((ErtsDrvEventState *) des1)->fd->id == ((ErtsDrvEventState *) des2)->fd->id)
- && (((ErtsDrvEventState *) des1)->fd->signo == ((ErtsDrvEventState *) des2)->fd->signo))
- ? 0 : 1);
+ ErtsSysFdType fd1 = ((ErtsDrvEventState *) des1)->fd;
+ ErtsSysFdType fd2 = ((ErtsDrvEventState *) des2)->fd;
+ if (fd1->signo == fd2->signo && fd1->id == fd2->id)
+ return 0;
+ return 1;
}
-#else
+#else /* !__OSE__ && !ERTS_SYS_CONTINOUS_FD_NUMBERS i.e. probably windows */
static SafeHashValue drv_ev_state_hash(void *des)
{
SafeHashValue val = (SafeHashValue) ((ErtsDrvEventState *) des)->fd;
@@ -1473,69 +1464,7 @@ static void drv_ev_state_free(void *des)
erts_smp_spin_unlock(&state_prealloc_lock);
}
#endif
-#ifdef __OSE__
-OseSignal *erl_drv_ose_get_input_signal(ErlDrvEvent drv_ev) {
- struct erts_sys_fd_type *ev = (struct erts_sys_fd_type *)drv_ev;
- ethr_mutex_lock(&ev->mtx);
- if (ev->imsgs == NULL) {
- ethr_mutex_unlock(&ev->mtx);
- return NULL;
- } else {
- ErtsPollOseMsgList *msg = ev->imsgs;
- OseSignal *sig = (OseSignal*)msg->data;
- ASSERT(msg->data);
- ev->imsgs = msg->next;
- ethr_mutex_unlock(&ev->mtx);
- erts_free(ERTS_ALC_T_FD_SIG_LIST,msg);
- restore(sig);
- return sig;
- }
-}
-
-OseSignal *erl_drv_ose_get_output_signal(ErlDrvEvent drv_ev) {
- struct erts_sys_fd_type *ev = (struct erts_sys_fd_type *)drv_ev;
- ethr_mutex_lock(&ev->mtx);
- if (ev->omsgs == NULL) {
- ethr_mutex_unlock(&ev->mtx);
- return NULL;
- } else {
- ErtsPollOseMsgList *msg = ev->omsgs;
- OseSignal *sig = (OseSignal*)msg->data;
- ASSERT(msg->data);
- ev->omsgs = msg->next;
- ethr_mutex_unlock(&ev->mtx);
- erts_free(ERTS_ALC_T_FD_SIG_LIST,msg);
- restore(sig);
- return sig;
- }
-}
-ErlDrvEvent erl_drv_ose_event_alloc(SIGSELECT signo, int id) {
- struct erts_sys_fd_type *ev = erts_alloc(ERTS_ALC_T_DRV_EV,
- sizeof(struct erts_sys_fd_type));
- ev->signo = signo;
- ev->id = id;
- ev->imsgs = NULL;
- ev->omsgs = NULL;
- ethr_mutex_init(&ev->mtx);
- return (ErlDrvEvent)ev;
-}
-
-void erl_drv_ose_event_free(ErlDrvEvent drv_ev) {
- struct erts_sys_fd_type *ev = (struct erts_sys_fd_type *)drv_ev;
- ethr_mutex_destroy(&ev->mtx);
- erts_free(ERTS_ALC_T_DRV_EV,ev);
-}
-
-void erl_drv_ose_event_fetch(ErlDrvEvent drv_ev, SIGSELECT *signo, int *id) {
- struct erts_sys_fd_type *ev = (struct erts_sys_fd_type *)drv_ev;
- if (signo)
- *signo = ev->signo;
- if (id)
- *id = ev->id;
-}
-
-#endif
void
ERTS_CIO_EXPORT(erts_init_check_io)(void)
{
diff --git a/erts/emulator/sys/common/erl_poll.h b/erts/emulator/sys/common/erl_poll.h
index e1ea8fb207..ce8dcd3f90 100644
--- a/erts/emulator/sys/common/erl_poll.h
+++ b/erts/emulator/sys/common/erl_poll.h
@@ -106,6 +106,23 @@ typedef Uint32 ErtsPollEvents;
#define ERTS_POLL_EV_ERR 4
#define ERTS_POLL_EV_NVAL 8
+#ifdef __OSE__
+
+typedef struct ErtsPollOseMsgList_ {
+ struct ErtsPollOseMsgList_ *next;
+ union SIGNAL *data;
+} ErtsPollOseMsgList;
+
+struct erts_sys_fd_type {
+ SIGSELECT signo;
+ ErlDrvOseEventId id;
+ ErtsPollOseMsgList *msgs;
+ ErlDrvOseEventId (*resolve_signal)(union SIGNAL *sig);
+ ethr_mutex mtx;
+};
+
+#endif
+
#elif ERTS_POLL_USE_EPOLL /* --- epoll ------------------------------- */
#include <sys/epoll.h>
@@ -229,9 +246,6 @@ ErtsPollEvents ERTS_POLL_EXPORT(erts_poll_control)(ErtsPollSet,
ErtsPollEvents,
int on,
int* wake_poller
-#ifdef __OSE__
- ,int (*decode)(OseSignal* sig, int* mode)
-#endif
);
void ERTS_POLL_EXPORT(erts_poll_controlv)(ErtsPollSet,
ErtsPollControlEntry [],
diff --git a/erts/emulator/sys/ose/erl_ose_sys.h b/erts/emulator/sys/ose/erl_ose_sys.h
index 8c72afa9a5..db8607b650 100644
--- a/erts/emulator/sys/ose/erl_ose_sys.h
+++ b/erts/emulator/sys/ose/erl_ose_sys.h
@@ -56,20 +56,6 @@
# include "sys/mman.h"
#endif
-typedef struct ErtsPollOseMsgList_ {
- struct ErtsPollOseMsgList_ *next;
- void *data;
-} ErtsPollOseMsgList;
-
-struct erts_sys_fd_type {
- SIGSELECT signo;
- int id;
- ErtsPollOseMsgList *imsgs;
- ErtsPollOseMsgList *omsgs;
- ethr_mutex mtx;
-};
-
-
/*
* Min number of async threads
*/
diff --git a/erts/emulator/sys/ose/erl_poll.c b/erts/emulator/sys/ose/erl_poll.c
index b1e256afc3..78dc275c06 100644
--- a/erts/emulator/sys/ose/erl_poll.c
+++ b/erts/emulator/sys/ose/erl_poll.c
@@ -103,7 +103,7 @@ typedef struct erts_sigsel_info_ ErtsSigSelInfo;
struct erts_sigsel_info_ {
ErtsSigSelInfo *next;
SIGSELECT signo;
- int (*decode)(OseSignal* sig, int* mode);
+ ErlDrvOseEventId (*decode)(union SIGNAL* sig);
ErtsSigSelItem *fds;
};
@@ -131,8 +131,10 @@ static int max_fds = -1;
/* signal list prototypes */
static ErtsSigSelInfo *get_sigsel_info(ErtsPollSet ps, SIGSELECT signo);
static ErtsSigSelItem *get_sigsel_item(ErtsPollSet ps, ErtsSysFdType fd);
-static ErtsSigSelInfo *add_sigsel_info(ErtsPollSet ps, ErtsSysFdType fd, int (*decode)(OseSignal* sig, int* mode));
-static ErtsSigSelItem *add_sigsel_item(ErtsPollSet ps, ErtsSysFdType fd, int (*decode)(OseSignal* sig, int* mode));
+static ErtsSigSelInfo *add_sigsel_info(ErtsPollSet ps, ErtsSysFdType fd,
+ ErlDrvOseEventId (*decode)(union SIGNAL* sig));
+static ErtsSigSelItem *add_sigsel_item(ErtsPollSet ps, ErtsSysFdType fd,
+ ErlDrvOseEventId (*decode)(union SIGNAL* sig));
static int del_sigsel_info(ErtsPollSet ps, ErtsSigSelInfo *info);
static int del_sigsel_item(ErtsPollSet ps, ErtsSigSelItem *item);
static int update_sigsel(ErtsPollSet ps);
@@ -170,7 +172,7 @@ get_sigsel_item(ErtsPollSet ps, ErtsSysFdType fd) {
static ErtsSigSelInfo *
add_sigsel_info(ErtsPollSet ps, ErtsSysFdType fd,
- int (*decode)(OseSignal* sig, int* mode)) {
+ ErlDrvOseEventId (*decode)(union SIGNAL* sig)) {
ErtsSigSelInfo *info = SEL_ALLOC(ERTS_ALC_T_POLLSET,
sizeof(ErtsSigSelInfo));
info->next = ps->info;
@@ -184,7 +186,7 @@ add_sigsel_info(ErtsPollSet ps, ErtsSysFdType fd,
static ErtsSigSelItem *
add_sigsel_item(ErtsPollSet ps, ErtsSysFdType fd,
- int (*decode)(OseSignal* sig, int* mode)) {
+ ErlDrvOseEventId (*decode)(union SIGNAL* sig)) {
ErtsSigSelInfo *info = get_sigsel_info(ps,fd->signo);
ErtsSigSelItem *item = SEL_ALLOC(ERTS_ALC_T_POLLSET,
sizeof(ErtsSigSelItem));
@@ -394,8 +396,7 @@ void erts_poll_interrupt_timed(ErtsPollSet ps,int set,erts_short_time_t msec) {
}
ErtsPollEvents erts_poll_control(ErtsPollSet ps, ErtsSysFdType fd,
- ErtsPollEvents pe, int on, int* do_wake,
- int(*decode)(OseSignal* sig, int* mode)) {
+ ErtsPollEvents pe, int on, int* do_wake) {
ErtsSigSelItem *curr;
ErtsPollEvents new_events;
int old_sig_count;
@@ -406,11 +407,17 @@ ErtsPollEvents erts_poll_control(ErtsPollSet ps, ErtsSysFdType fd,
ERTS_POLLSET_LOCK(ps);
+ if (on && (pe & ERTS_POLL_EV_IN) && (pe & ERTS_POLL_EV_OUT)) {
+ /* Check to make sure both in and out are not used at the same time */
+ new_events = ERTS_POLL_EV_NVAL;
+ goto done;
+ }
+
curr = get_sigsel_item(ps, fd);
old_sig_count = ps->sig_count;
if (curr == NULL && on) {
- curr = add_sigsel_item(ps, fd, decode);
+ curr = add_sigsel_item(ps, fd, fd->resolve_signal);
} else if (curr == NULL && !on) {
new_events = ERTS_POLL_EV_NVAL;
goto done;
@@ -451,7 +458,7 @@ int erts_poll_wait(ErtsPollSet ps,
SysTimeval *utvp) {
int res = ETIMEDOUT, no_fds, currid = 0;
OSTIME timeout;
- OseSignal *sig;
+ union SIGNAL *sig;
// HARDTRACEF("%ux: In erts_poll_wait",ps);
if (ps->interrupt == (PROCESS)0)
ps->interrupt = current_process();
@@ -515,8 +522,7 @@ int erts_poll_wait(ErtsPollSet ps,
}
{
ErtsSigSelInfo *info = get_sigsel_info(ps, sig->sig_no);
- int mode = -1;
- struct erts_sys_fd_type fd = { sig->sig_no, info->decode(sig, &mode) };
+ struct erts_sys_fd_type fd = { sig->sig_no, info->decode(sig) };
ErtsSigSelItem *item = get_sigsel_item(ps, &fd);
ASSERT(sig);
@@ -546,38 +552,16 @@ int erts_poll_wait(ErtsPollSet ps,
erts_send_error_to_logger_nogl(dsbufp);
timeout = 0;
ASSERT(0);
- } else if (mode == -1 && item->events == (ERTS_POLL_EV_IN|ERTS_POLL_EV_OUT)) {
- erts_dsprintf_buf_t *dsbufp = erts_create_logger_dsbuf();
- erts_dsprintf(
- dsbufp,
- "erts_poll_wait() failed: found ambigous signal id %d (signo %u) "
- "(curr_proc 0x%x /sender 0x%x)\n You have to give a specify a mode "
- "in the resolve_signal callback for this signal.\n",
- fd.id, fd.signo, current_process(), sender(&sig));
- erts_send_error_to_logger_nogl(dsbufp);
- timeout = 0;
- ASSERT(0);
- } else {
+ } else {
int i;
struct erts_sys_fd_type *fd = NULL;
ErtsPollOseMsgList *tl,*new;
- /* Figure out which mode to set and which queue to store
- the signal in */
- if (mode == -1)
- mode = item->events;
- else if (mode == 0)
- mode = ERTS_POLL_EV_IN;
- else if (mode == 1)
- mode = ERTS_POLL_EV_OUT;
- else
- abort();
-
/* Check if this fd has already been triggered by a previous signal */
for (i = 0; i < currid;i++) {
if (pr[i].fd == item->fd) {
fd = pr[i].fd;
- pr[i].events |= mode;
+ pr[i].events |= item->events;
break;
}
}
@@ -585,7 +569,7 @@ int erts_poll_wait(ErtsPollSet ps,
/* First time this fd is triggered */
if (fd == NULL) {
pr[currid].fd = item->fd;
- pr[currid].events = mode;
+ pr[currid].events = item->events;
fd = item->fd;
timeout = 0;
currid++;
@@ -597,16 +581,10 @@ int erts_poll_wait(ErtsPollSet ps,
new->data = sig;
ethr_mutex_lock(&fd->mtx);
- if (mode & ERTS_POLL_EV_IN)
- tl = fd->imsgs;
- else if (mode & ERTS_POLL_EV_OUT)
- tl = fd->omsgs;
+ tl = fd->msgs;
if (tl == NULL) {
- if (mode & ERTS_POLL_EV_IN)
- fd->imsgs = new;
- else if (mode & ERTS_POLL_EV_OUT)
- fd->omsgs = new;
+ fd->msgs = new;
} else {
while (tl->next != NULL)
tl = tl->next;
@@ -742,3 +720,53 @@ void erts_poll_init(void)
HARDTRACEF("Out %s", __FUNCTION__);
}
+
+
+/* OSE driver functions */
+
+union SIGNAL *erl_drv_ose_get_signal(ErlDrvEvent drv_ev) {
+ struct erts_sys_fd_type *ev = (struct erts_sys_fd_type *)drv_ev;
+ ethr_mutex_lock(&ev->mtx);
+ if (ev->msgs == NULL) {
+ ethr_mutex_unlock(&ev->mtx);
+ return NULL;
+ } else {
+ ErtsPollOseMsgList *msg = ev->msgs;
+ union SIGNAL *sig = (union SIGNAL*)msg->data;
+ ASSERT(msg->data);
+ ev->msgs = msg->next;
+ ethr_mutex_unlock(&ev->mtx);
+ erts_free(ERTS_ALC_T_FD_SIG_LIST,msg);
+ restore(sig);
+ return sig;
+ }
+}
+
+ErlDrvEvent
+erl_drv_ose_event_alloc(SIGSELECT signo, ErlDrvOseEventId id,
+ ErlDrvOseEventId (*resolve_signal)(union SIGNAL *sig)) {
+ struct erts_sys_fd_type *ev = erts_alloc(ERTS_ALC_T_DRV_EV,
+ sizeof(struct erts_sys_fd_type));
+ ev->signo = signo;
+ ev->id = id;
+ ev->msgs = NULL;
+ ev->resolve_signal = resolve_signal;
+ ethr_mutex_init(&ev->mtx);
+ return (ErlDrvEvent)ev;
+}
+
+void erl_drv_ose_event_free(ErlDrvEvent drv_ev) {
+ struct erts_sys_fd_type *ev = (struct erts_sys_fd_type *)drv_ev;
+ ASSERT(ev->msgs == NULL);
+ ethr_mutex_destroy(&ev->mtx);
+ erts_free(ERTS_ALC_T_DRV_EV,ev);
+}
+
+void erl_drv_ose_event_fetch(ErlDrvEvent drv_ev, SIGSELECT *signo,
+ ErlDrvOseEventId *id) {
+ struct erts_sys_fd_type *ev = (struct erts_sys_fd_type *)drv_ev;
+ if (signo)
+ *signo = ev->signo;
+ if (id)
+ *id = ev->id;
+}
diff --git a/erts/emulator/sys/ose/sys.c b/erts/emulator/sys/ose/sys.c
index b786d19ecf..ad82e4587d 100644
--- a/erts/emulator/sys/ose/sys.c
+++ b/erts/emulator/sys/ose/sys.c
@@ -576,7 +576,7 @@ static void ready_output(ErlDrvData, ErlDrvEvent);
static void output(ErlDrvData, char*, ErlDrvSizeT);
static void outputv(ErlDrvData, ErlIOVec*);
static void stop_select(ErlDrvEvent, void*);
-static int resolve_signal(OseSignal* sig, int *mode) {
+static ErlDrvOseEventId resolve_signal(union SIGNAL* sig) {
return sig->sig_no == ERTS_SIGNAL_FD_DRV_ASYNC ? sig->sys_async.type : -1;
}
@@ -605,8 +605,7 @@ struct erl_drv_entry spawn_driver_entry = {
ERL_DRV_EXTENDED_MINOR_VERSION,
ERL_DRV_FLAG_USE_PORT_LOCKING,
NULL, NULL,
- stop_select,
- resolve_signal
+ stop_select
};
struct erl_drv_entry fd_driver_entry = {
NULL,
@@ -631,8 +630,7 @@ struct erl_drv_entry fd_driver_entry = {
0, /* ERL_DRV_FLAGs */
NULL, /* handle2 */
NULL, /* process_exit */
- stop_select,
- resolve_signal
+ stop_select
};
static int set_driver_data(ErlDrvPort port_num,
@@ -645,7 +643,7 @@ static int set_driver_data(ErlDrvPort port_num,
{
Port *prt;
ErtsSysReportExit *report_exit;
- OseSignal *sig;
+ union SIGNAL *sig;
/*erts_fprintf(stderr, " %s / pid %x / ofd %d / ifd %d\n",
__FUNCTION__, current_process(), ofd, ifd);*/
@@ -664,10 +662,12 @@ static int set_driver_data(ErlDrvPort port_num,
if (read_write & DO_READ)
report_exit->in_sig_descr =
- erl_drv_ose_event_alloc(ERTS_SIGNAL_FD_DRV_ASYNC, ifd);
+ erl_drv_ose_event_alloc(ERTS_SIGNAL_FD_DRV_ASYNC, ifd,
+ resolve_signal);
if (read_write & DO_WRITE)
report_exit->out_sig_descr =
- erl_drv_ose_event_alloc(ERTS_SIGNAL_FD_DRV_ASYNC, ofd);
+ erl_drv_ose_event_alloc(ERTS_SIGNAL_FD_DRV_ASYNC, ofd,
+ resolve_signal);
report_exit_list = report_exit;
}
@@ -684,7 +684,8 @@ static int set_driver_data(ErlDrvPort port_num,
driver_data[ifd].alive = 1;
driver_data[ifd].status = 0;
driver_data[ifd].in_sig_descr =
- erl_drv_ose_event_alloc(ERTS_SIGNAL_FD_DRV_ASYNC,ifd);
+ erl_drv_ose_event_alloc(ERTS_SIGNAL_FD_DRV_ASYNC,ifd,
+ resolve_signal);
driver_data[ifd].in_proc = create_process(OS_PRI_PROC,"beam_fd_reader",
fd_reader_process, 0x800,
@@ -700,7 +701,8 @@ static int set_driver_data(ErlDrvPort port_num,
if (read_write & DO_WRITE) {
driver_data[ifd].ofd = ofd;
driver_data[ifd].out_sig_descr =
- erl_drv_ose_event_alloc(ERTS_SIGNAL_FD_DRV_ASYNC,ofd);
+ erl_drv_ose_event_alloc(ERTS_SIGNAL_FD_DRV_ASYNC,ofd,
+ resolve_signal);
driver_data[ifd].pdl = driver_pdl_create(port_num);
driver_data[ifd].out_proc =
create_process(OS_PRI_PROC,"beam_fd_writer",
@@ -729,7 +731,8 @@ static int set_driver_data(ErlDrvPort port_num,
driver_data[ofd].alive = 1;
driver_data[ofd].status = 0;
driver_data[ofd].in_sig_descr =
- erl_drv_ose_event_alloc(ERTS_SIGNAL_FD_DRV_ASYNC,ofd);
+ erl_drv_ose_event_alloc(ERTS_SIGNAL_FD_DRV_ASYNC,ofd,
+ resolve_signal);
driver_data[ofd].out_sig_descr = driver_data[ofd].in_sig_descr;
driver_data[ofd].out_proc =
create_process(OS_PRI_PROC, "beam_fd_writer",
@@ -783,7 +786,7 @@ static ErlDrvData spawn_start(ErlDrvPort port_num,
}
OS_PROCESS(fd_reader_process) {
- OseSignal *sig;
+ union SIGNAL *sig;
PROCESS parent;
int fd;
byte *read_buf;
@@ -844,7 +847,7 @@ OS_PROCESS(fd_reader_process) {
}
OS_PROCESS(fd_writer_process) {
- OseSignal *sig;
+ union SIGNAL *sig;
PROCESS parent;
int fd;
SIGSELECT sigsel[] = { 1, ERTS_SIGNAL_FD_DRV_CONFIG,
@@ -1105,7 +1108,7 @@ static void outputv(ErlDrvData e, ErlIOVec* ev)
driver_pdl_unlock(driver_data[fd].pdl);
}
else {
- OseSignal *sig;
+ union SIGNAL *sig;
/* fprintf(stderr,"0x%x: outputv, enq+sel\n", current_process()); */
driver_enqv(ix, ev, 0); /* n is the skip value */
driver_pdl_unlock(driver_data[fd].pdl);
@@ -1151,7 +1154,7 @@ static void output(ErlDrvData e, char* buf, ErlDrvSizeT len)
set_busy_port(ix, 1);
}
else {
- OseSignal *sig;
+ union SIGNAL *sig;
/* fprintf(stderr,"0x%x: output, enq+select\n", current_process()); */
#if 0
iv[0].iov_base = lbp;
@@ -1219,13 +1222,13 @@ static int port_inp_failure(ErlDrvPort port_num, ErlDrvEvent ready_fd, int res)
}
static int async_read(ErlDrvEvent fd, byte *buff, int size) {
- OseSignal *sigptr = erl_drv_ose_get_input_signal(fd);
+ union SIGNAL *sigptr = erl_drv_ose_get_signal(fd);
int res = sigptr->sys_async.res;
if (res > 0)
memcpy(buff,sigptr->sys_async.buff,sigptr->sys_async.res);
errno = sigptr->sys_async.errno_copy;
send(&sigptr,sender(&sigptr));
- ASSERT(erl_drv_ose_get_input_signal(fd) == NULL);
+ ASSERT(erl_drv_ose_get_signal(fd) == NULL);
return res;
}
@@ -1360,7 +1363,7 @@ static void ready_output(ErlDrvData e, ErlDrvEvent ready_fd)
{
int fd = (int)(long)e;
ErlDrvPort ix = driver_data[fd].port_num;
- OseSignal *sigptr = erl_drv_ose_get_output_signal(ready_fd);
+ union SIGNAL *sigptr = erl_drv_ose_get_signal(ready_fd);
ssize_t n;
struct iovec* iv;
int vsize;
@@ -1374,7 +1377,7 @@ static void ready_output(ErlDrvData e, ErlDrvEvent ready_fd)
driver_select(ix, ready_fd, ERL_DRV_WRITE, 0);
set_busy_port(ix, 0);
free_buf(&sigptr);
- if ((sigptr = erl_drv_ose_get_output_signal(ready_fd)) == NULL)
+ if ((sigptr = erl_drv_ose_get_signal(ready_fd)) == NULL)
return; /* 0; */
continue;
}
@@ -1384,7 +1387,7 @@ static void ready_output(ErlDrvData e, ErlDrvEvent ready_fd)
if (errno == ERRNO_BLOCK || errno == EINTR) {
/* fprintf(stderr,"0x%x: ready_output, send to %x\n", current_process(),driver_data[fd].out_proc);*/
send(&sigptr,driver_data[fd].out_proc);
- if ((sigptr = erl_drv_ose_get_output_signal(ready_fd)) == NULL)
+ if ((sigptr = erl_drv_ose_get_signal(ready_fd)) == NULL)
return; /* 0; */
continue;
} else {
@@ -1393,7 +1396,7 @@ static void ready_output(ErlDrvData e, ErlDrvEvent ready_fd)
free_buf(&sigptr);
driver_select(ix, ready_fd, ERL_DRV_WRITE, 0);
driver_failure_posix(ix, res);
- if ((sigptr = erl_drv_ose_get_output_signal(ready_fd)) == NULL)
+ if ((sigptr = erl_drv_ose_get_signal(ready_fd)) == NULL)
return; /* -1; */
continue;
}
@@ -1410,7 +1413,7 @@ static void ready_output(ErlDrvData e, ErlDrvEvent ready_fd)
else
continue;
}
- sigptr = erl_drv_ose_get_output_signal(ready_fd);
+ sigptr = erl_drv_ose_get_signal(ready_fd);
}
return; /* 0; */
}
@@ -1752,7 +1755,7 @@ erts_sys_main_thread(void)
while (1) {
static const SIGSELECT sigsel[] = {0};
- OseSignal *msg = receive(sigsel);
+ union SIGNAL *msg = receive(sigsel);
fprintf(stderr,"Main thread got message %d from 0x%x!!\r\n",
msg->sig_no, sender(&msg));