From: Martin Ling Date: Fri, 20 Dec 2013 17:45:46 +0000 (+0000) Subject: Use new libserialport event set API to make GPollFDs for serial sources. X-Git-Tag: libsigrok-0.3.0~422 X-Git-Url: http://sigrok.org/gitweb/?a=commitdiff_plain;h=ba1949f583de322e74f43eb880529155a763a84f;p=libsigrok.git Use new libserialport event set API to make GPollFDs for serial sources. --- diff --git a/hardware/common/serial.c b/hardware/common/serial.c index 0d26b464..891fd02d 100644 --- a/hardware/common/serial.c +++ b/hardware/common/serial.c @@ -638,25 +638,69 @@ SR_PRIV int sr_serial_extract_options(GSList *options, const char **serial_devic return SR_OK; } -SR_PRIV int serial_source_add(struct sr_serial_dev_inst *serial, int events, - int timeout, sr_receive_data_callback_t cb, void *cb_data) -{ #ifdef _WIN32 - return SR_ERR; +typedef HANDLE event_handle; #else - int fd; - sp_get_port_handle(serial->data, &fd); - return sr_source_add(fd, events, timeout, cb, cb_data); +typedef int event_handle; #endif + +SR_PRIV int serial_source_add(struct sr_serial_dev_inst *serial, int events, + int timeout, sr_receive_data_callback_t cb, void *cb_data) +{ + enum sp_event mask = 0; + unsigned int i; + + if (sp_new_event_set(&serial->event_set) != SP_OK) + return SR_ERR; + + if (events & G_IO_IN) + mask |= SP_EVENT_RX_READY; + if (events & G_IO_OUT) + mask |= SP_EVENT_TX_READY; + if (events & G_IO_ERR) + mask |= SP_EVENT_ERROR; + + if (sp_add_port_events(serial->event_set, serial->data, mask) != SP_OK) { + sp_free_event_set(serial->event_set); + return SR_ERR; + } + + serial->pollfds = (GPollFD *) g_malloc0(sizeof(GPollFD) * serial->event_set->count); + + for (i = 0; i < serial->event_set->count; i++) { + + serial->pollfds[i].fd = ((event_handle *) serial->event_set->handles)[i]; + + mask = serial->event_set->masks[i]; + + if (mask & SP_EVENT_RX_READY) + serial->pollfds[i].events |= G_IO_IN; + if (mask & SP_EVENT_TX_READY) + serial->pollfds[i].events |= G_IO_OUT; + if (mask & SP_EVENT_ERROR) + serial->pollfds[i].events |= G_IO_ERR; + + if (sr_session_source_add_pollfd(&serial->pollfds[i], + timeout, cb, cb_data) != SR_OK) + return SR_ERR; + } + + return SR_OK; } SR_PRIV int serial_source_remove(struct sr_serial_dev_inst *serial) { -#ifdef _WIN32 - return SR_ERR; -#else - int fd; - sp_get_port_handle(serial->data, &fd); - return sr_source_remove(fd); -#endif + unsigned int i; + + for (i = 0; i < serial->event_set->count; i++) + if (sr_session_source_remove_pollfd(&serial->pollfds[i]) != SR_OK) + return SR_ERR; + + g_free(serial->pollfds); + sp_free_event_set(serial->event_set); + + serial->pollfds = NULL; + serial->event_set = NULL; + + return SR_OK; } diff --git a/libsigrok-internal.h b/libsigrok-internal.h index 9c00d9bd..d9def32e 100644 --- a/libsigrok-internal.h +++ b/libsigrok-internal.h @@ -88,6 +88,10 @@ struct sr_serial_dev_inst { int nonblocking; /** libserialport port handle */ struct sp_port *data; + /** libserialport event set */ + struct sp_event_set *event_set; + /** GPollFDs for event polling */ + GPollFD *pollfds; }; #endif