From 4a6850e522b91eb009ddd0ed9d9f542f1baf1bee Mon Sep 17 00:00:00 2001 From: Jonas Karlsson Date: Fri, 21 Feb 2014 14:01:38 +0100 Subject: ose: Updating event and signal API for OSE --- erts/emulator/beam/erl_driver.h | 6 +++--- erts/emulator/drivers/ose/ose_signal_drv.c | 8 ++++---- erts/emulator/sys/common/erl_poll.h | 1 + erts/emulator/sys/ose/erl_poll.c | 12 +++++++----- lib/ose/doc/src/ose_erl_driver.xml | 9 +++++---- lib/ose/doc/src/ose_signals_chapter.xml | 23 +++++++++++++++++++++-- 6 files changed, 41 insertions(+), 18 deletions(-) diff --git a/erts/emulator/beam/erl_driver.h b/erts/emulator/beam/erl_driver.h index a15b0e17f5..5517c26ba4 100644 --- a/erts/emulator/beam/erl_driver.h +++ b/erts/emulator/beam/erl_driver.h @@ -682,11 +682,11 @@ EXTERN int erl_drv_getenv(char *key, char *value, size_t *value_size); #ifdef __OSE__ 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 ErlDrvEvent erl_drv_ose_event_alloc(SIGSELECT sig, ErlDrvOseEventId handle, + ErlDrvOseEventId (*resolve_signal)(union SIGNAL *sig), void *extra); EXTERN void erl_drv_ose_event_free(ErlDrvEvent ev); EXTERN void erl_drv_ose_event_fetch(ErlDrvEvent ev, SIGSELECT *sig, - ErlDrvOseEventId *id); + ErlDrvOseEventId *handle, void **extra); #endif #endif /* !ERL_DRIVER_TYPES_ONLY */ diff --git a/erts/emulator/drivers/ose/ose_signal_drv.c b/erts/emulator/drivers/ose/ose_signal_drv.c index 1335bffe18..4929b53856 100644 --- a/erts/emulator/drivers/ose/ose_signal_drv.c +++ b/erts/emulator/drivers/ose/ose_signal_drv.c @@ -504,12 +504,12 @@ static void outputv(ErlDrvData driver_data, ErlIOVec *ev) ctxt->perm_events[1] = erl_drv_ose_event_alloc(ERTS_SIGNAL_OSE_DRV_ATTACH,(int)ctxt->spid, - resolve_signal); + resolve_signal, NULL); 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, - resolve_signal); + resolve_signal, NULL); driver_select(ctxt->port,ctxt->perm_events[0],ERL_DRV_READ|ERL_DRV_USE,1); start(ctxt->spid); @@ -679,7 +679,7 @@ static void outputv(ErlDrvData driver_data, ErlIOVec *ev) for (i = 0, j = 0; i < event_cnt || j < ctxt->event_cnt; ) { if (ctxt->events) - erl_drv_ose_event_fetch(ctxt->events[j],&tmp_signo,NULL); + erl_drv_ose_event_fetch(ctxt->events[j],&tmp_signo,NULL,NULL); if (signo == tmp_signo) { events[i++] = ctxt->events[j++]; @@ -687,7 +687,7 @@ static void outputv(ErlDrvData driver_data, ErlIOVec *ev) } else if (signo < tmp_signo || !ctxt->events) { /* New signal to select on */ events[i] = erl_drv_ose_event_alloc(signo,(int)ctxt->spid, - resolve_signal); + resolve_signal, NULL); driver_select(ctxt->port,events[i++],ERL_DRV_READ|ERL_DRV_USE,1); EV_GET_UINT32(ev,&signo,&p,&q); } else { diff --git a/erts/emulator/sys/common/erl_poll.h b/erts/emulator/sys/common/erl_poll.h index ce8dcd3f90..2f1c05f401 100644 --- a/erts/emulator/sys/common/erl_poll.h +++ b/erts/emulator/sys/common/erl_poll.h @@ -119,6 +119,7 @@ struct erts_sys_fd_type { ErtsPollOseMsgList *msgs; ErlDrvOseEventId (*resolve_signal)(union SIGNAL *sig); ethr_mutex mtx; + void *extra; }; #endif diff --git a/erts/emulator/sys/ose/erl_poll.c b/erts/emulator/sys/ose/erl_poll.c index 78dc275c06..ca1ed6e53a 100644 --- a/erts/emulator/sys/ose/erl_poll.c +++ b/erts/emulator/sys/ose/erl_poll.c @@ -547,8 +547,8 @@ int erts_poll_wait(ErtsPollSet ps, erts_dsprintf( dsbufp, "erts_poll_wait() failed: found unkown signal id %d (signo %u) " - "(curr_proc 0x%x /sender 0x%x)\n", - fd.id, fd.signo, current_process(), sender(&sig)); + "(curr_proc 0x%x)\n", + fd.id, fd.signo, current_process()); erts_send_error_to_logger_nogl(dsbufp); timeout = 0; ASSERT(0); @@ -737,17 +737,17 @@ union SIGNAL *erl_drv_ose_get_signal(ErlDrvEvent drv_ev) { 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)) { + ErlDrvOseEventId (*resolve_signal)(union SIGNAL *sig), void *extra) { struct erts_sys_fd_type *ev = erts_alloc(ERTS_ALC_T_DRV_EV, sizeof(struct erts_sys_fd_type)); ev->signo = signo; + ev->extra = extra; ev->id = id; ev->msgs = NULL; ev->resolve_signal = resolve_signal; @@ -763,10 +763,12 @@ void erl_drv_ose_event_free(ErlDrvEvent drv_ev) { } void erl_drv_ose_event_fetch(ErlDrvEvent drv_ev, SIGSELECT *signo, - ErlDrvOseEventId *id) { + ErlDrvOseEventId *id, void **extra) { struct erts_sys_fd_type *ev = (struct erts_sys_fd_type *)drv_ev; if (signo) *signo = ev->signo; + if (extra) + *extra = ev->extra; if (id) *id = ev->id; } diff --git a/lib/ose/doc/src/ose_erl_driver.xml b/lib/ose/doc/src/ose_erl_driver.xml index 93cbd91be7..1d89d7aeea 100644 --- a/lib/ose/doc/src/ose_erl_driver.xml +++ b/lib/ose/doc/src/ose_erl_driver.xml @@ -68,12 +68,13 @@ - ErlDrvEventerl_drv_ose_event_alloc(SIGSELECT signo, ErlDrvOseEventId id, ErlDrvOseEventId (*resolve_signal)(union SIGNAL* sig)) + ErlDrvEventerl_drv_ose_event_alloc(SIGSELECT signo, ErlDrvOseEventId id, ErlDrvOseEventId (*resolve_signal)(union SIGNAL* sig), void *extra)

Create a new ErlDrvEvent associated with signo, id and uses the resolve_signal function to extract - the id from a signal with signo. See + the id from a signal with signo. The extra + parameter can be used for additional data. See Signals in a Linked-in driver in the OSE User's Guide.

@@ -89,10 +90,10 @@
- voiderl_drv_ose_event_fetch(ErlDrvEvent drv_event, SIGSELECT *signo, int *id) + voiderl_drv_ose_event_fetch(ErlDrvEvent drv_event, SIGSELECT *signo, ErlDrvOseEventId *id, void **extra) -

Write the signal number and id associated with drv_event +

Write the signal number, id and any extra data associated with drv_event into *signo and *id respectively. NULL can be also passed as signo or id in order to ignore that field.

diff --git a/lib/ose/doc/src/ose_signals_chapter.xml b/lib/ose/doc/src/ose_signals_chapter.xml index 85849e1a39..c8d98f4099 100644 --- a/lib/ose/doc/src/ose_signals_chapter.xml +++ b/lib/ose/doc/src/ose_signals_chapter.xml @@ -77,7 +77,12 @@ in this case the port id that we got in the start callback is used. The third argument is a function pointer to a function that can - be used to figure out the id from a given signal. There is a complete + be used to figure out the id from a given signal. The fourth argument can + point to any additional data you might want to associate with the event. + There is a complete. You can examine the data contained in the event with + erl_drv_ose_event_fetch + , eg: + erl_drv_ose_event_fetch(event, &signal, &port, (void **)&extra); example of what this could look like in the next section. It is very important to issue the driver_select call before @@ -132,8 +137,12 @@ static ErlDrvSSizeT control(ErlDrvData driver_data, unsigned int cmd, char **rbuf, ErlDrvSizeT rlen) { ErlDrvPort port = (ErlDrvPort)driver_data; + /* An example of extra data to associate with the event */ + char *extra_data = driver_alloc(80); + snprintf("extra_data, "Event, sig_no: 1234, and port: %d", port); + /* Create a new event to select on */ - ErlDrvOseEvent evt = erl_drv_ose_event_alloc(1234,port,resolver); + ErlDrvOseEvent evt = erl_drv_ose_event_alloc(1234,port,resolver, extra_data); /* Make sure to do the select call _BEFORE_ the signal arrives. The signal might get lost if the hunt call is done before the @@ -147,11 +156,16 @@ static ErlDrvSSizeT control(ErlDrvData driver_data, unsigned int cmd, } static void ready_input(ErlDrvData driver_data, ErlDrvEvent evt) { + char *extra_data; /* Get the first signal payload from the event */ union SIGNAL *sig = erl_drv_ose_get_signal(evt); ErlDrvPort port = (ErlDrvPort)driver_data; while (sig != NULL) { if (sig->signo == 1234) { + /* Print out the string we added as the extra parameter */ + erl_drv_ose_event_fetch(evt, NULL, NULL, (void **)&extra_data); + printf("We've received: %s\n", extra_data); + /* If it is our signal we send a message with the sender of the signal to the controlling erlang process */ ErlDrvTermData reply[] = { ERL_DRV_UINT, (ErlDrvUInt)sender(&sig) }; @@ -172,6 +186,11 @@ static void ready_input(ErlDrvData driver_data, ErlDrvEvent evt) { static void stop_select(ErlDrvEvent event, void *reserved) { + /* Free the extra_data */ + erl_drv_ose_event_fetch(evt, NULL, NULL, (void **)&extra_data); + driver_free(extra_data); + + /* Free the event itself */ erl_drv_ose_event_free(event); } -- cgit v1.2.3