Skip to content

Commit

Permalink
Abort pin monitoring on Linux for devices that don't support it
Browse files Browse the repository at this point in the history
For some serial devices, such as ttyACM* USB devices, the ioctl(TIOCMIWAIT) returns an error. Now if an error occurs, we propogate it to the .NET implementation which already correctly ends the monitoring thread.

Previously, the error was ignored in a loop resulting in 100% CPU utilization.

Issue: DOTNET-85, #22
  • Loading branch information
jcurl committed May 5, 2017
1 parent 2c3c12f commit a41f0cc
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 2 deletions.
25 changes: 23 additions & 2 deletions dll/serialunix/libnserial/modem.c
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,13 @@ static serialmodemevent_t waitformodemevent(struct modemstate *mstate)
risignal = -1;

if (ioctl(mstate->handle->fd, TIOCMIWAIT, signals) < 0) {
if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR) {
return MODEMEVENT_NONE;
}

// Some USB drivers don't support modem signals.
mstate->serialerror = ERRMSG_IOCTL;
mstate->posixerrno = errno;
return -1;
}

Expand Down Expand Up @@ -356,10 +362,17 @@ static void *modemeventthread(void *ptr)

while (TRUE) {
result = waitformodemevent(mstate);
if (result != MODEMEVENT_NONE && result != -1) {
if (result == -1) {
// We have a serious issue. We stop the thread. The error
// was already set by waitformodemevent.
mstate->eventresult = MODEMEVENT_NONE;
pthread_exit(NULL);
}
if (result != MODEMEVENT_NONE) {
mstate->eventresult = result;
pthread_exit(NULL);
}
// else we just keep polling.
}
}
#endif
Expand Down Expand Up @@ -403,9 +416,10 @@ NSERIAL_EXPORT serialmodemevent_t WINAPI serial_waitformodemevent(struct serialh
handle->modemstate = &mstate;
mstate.handle = handle;
mstate.waitevent = event;
mstate.eventresult = 0;
pthread_mutex_unlock(&(handle->modemmutex));

// We create the thread to wait on it afterwards, as we can
// make that thread cancellable.
result = pthread_create(&(handle->modemthread), NULL,
modemeventthread, &mstate);
if (result == -1) {
Expand All @@ -421,6 +435,13 @@ NSERIAL_EXPORT serialmodemevent_t WINAPI serial_waitformodemevent(struct serialh
return -1;
}

if (mstate.serialerror != 0) {
errno = mstate.posixerrno;
serial_seterror(handle, mstate.serialerror);
handle->modemstate = NULL;
return -1;
}

handle->modemstate = NULL;
return mstate.eventresult & event;
#else
Expand Down
1 change: 1 addition & 0 deletions dll/serialunix/libnserial/serialhandle.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ struct modemstate {
serialmodemevent_t waitevent;
serialmodemevent_t eventresult;
int serialerror;
int posixerrno;
};

// Maximum number of ports we have in the port descrip
Expand Down

0 comments on commit a41f0cc

Please sign in to comment.