Skip to content

Commit

Permalink
Rare race condition found in void* rx_loop (void* arg) impacting cl…
Browse files Browse the repository at this point in the history
…eaning up blocked clients during file close.

- Fix for bug #66
- Added further log_trace calls to trace better.
  • Loading branch information
Deniz-Eren committed May 21, 2024
1 parent 67db0d4 commit 5085a14
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 21 deletions.
2 changes: 1 addition & 1 deletion config/PROGRAM_VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.3.1
1.3.2
55 changes: 35 additions & 20 deletions src/resmgr.c
Original file line number Diff line number Diff line change
Expand Up @@ -657,6 +657,8 @@ void* rx_loop (void* arg) {
}

while (1) {
int status = -1;

pthread_mutex_lock(&ocb->rx.mutex);

while ((!resmgr->shutdown)
Expand All @@ -675,30 +677,23 @@ void* rx_loop (void* arg) {
pthread_exit(NULL);
}

if (ocb->rx.blocked_clients != NULL) {
struct can_msg* canmsg = dequeue_peek(ocb->rx.queue);

if (canmsg == NULL) {
continue;
}
struct can_msg* canmsg = dequeue_peek(ocb->rx.queue);

blocked_client_t* client = ocb->rx.blocked_clients;
if (canmsg == NULL) {
continue;
}

while (client != NULL) {
pthread_mutex_lock(&ocb->rx.mutex);
msg_again.rcvid = client->rcvid;
pthread_mutex_unlock(&ocb->rx.mutex);
pthread_mutex_lock(&ocb->rx.mutex);
blocked_client_t* client = ocb->rx.blocked_clients;

if (ocb->rx.queue != NULL && msg_again.rcvid != -1) {
if (MsgSend(coid, &msg_again, sizeof(msg_again_t), NULL, 0)
== -1)
{
log_err("rx_loop MsgSend error: %s\n", strerror(errno));
}
}
msg_again.rcvid = client->rcvid;
pthread_mutex_unlock(&ocb->rx.mutex);

client = client->next;
}
if ((status = MsgSend(
coid, &msg_again, sizeof(msg_again_t), NULL, 0 )) == -1)
{
log_err( "rx_loop MsgSend status: %d, error: %s\n",
status, strerror(errno) );
}
}

Expand Down Expand Up @@ -1222,6 +1217,8 @@ int io_devctl (resmgr_context_t* ctp, io_devctl_t* msg, RESMGR_OCB_T* _ocb) {
case CAN_DEVCTL_READ_CANMSG_EXT: // e.g. canctl -u0,rx0 -r
{
if (_ocb->resmgr->channel_type == TX_CHANNEL) {
log_trace("CAN_DEVCTL_READ_CANMSG_EXT: Input/output error\n");

return EIO; // Input/output error
}

Expand Down Expand Up @@ -1266,6 +1263,8 @@ int io_devctl (resmgr_context_t* ctp, io_devctl_t* msg, RESMGR_OCB_T* _ocb) {
pthread_cond_signal(&_ocb->rx.cond);
pthread_mutex_unlock(&_ocb->rx.mutex);

log_trace("CAN_DEVCTL_READ_CANMSG_EXT: _RESMGR_NOREPLY\n");

return _RESMGR_NOREPLY;
}

Expand All @@ -1274,6 +1273,8 @@ int io_devctl (resmgr_context_t* ctp, io_devctl_t* msg, RESMGR_OCB_T* _ocb) {
case CAN_DEVCTL_WRITE_CANMSG_EXT: // e.g. canctl -u0,rx0 -w0x22,1,0x55
{
if (_ocb->resmgr->channel_type == RX_CHANNEL) {
log_trace("CAN_DEVCTL_WRITE_CANMSG_EXT: Input/output error\n");

return EIO; // Input/output error
}

Expand Down Expand Up @@ -1501,6 +1502,10 @@ int io_devctl (resmgr_context_t* ctp, io_devctl_t* msg, RESMGR_OCB_T* _ocb) {
case CAN_DEVCTL_RX_FRAME_RAW_BLOCK: // e.g. candump -u0,rx0
{
if (_ocb->resmgr->channel_type == TX_CHANNEL) {
log_trace( "CAN_DEVCTL_RX_FRAME_RAW_%s: Input/output error\n",
msg->i.dcmd == CAN_DEVCTL_RX_FRAME_RAW_BLOCK
? "BLOCK" : "NOBLOCK" );

return EIO; // Input/output error
}

Expand Down Expand Up @@ -1548,9 +1553,17 @@ int io_devctl (resmgr_context_t* ctp, io_devctl_t* msg, RESMGR_OCB_T* _ocb) {
pthread_cond_signal(&_ocb->rx.cond);
pthread_mutex_unlock(&_ocb->rx.mutex);

log_trace( "CAN_DEVCTL_RX_FRAME_RAW_%s: _RESMGR_NOREPLY\n",
msg->i.dcmd == CAN_DEVCTL_RX_FRAME_RAW_BLOCK
? "BLOCK" : "NOBLOCK" );

return _RESMGR_NOREPLY; /* put the client in block state */
}
else { // CAN_DEVCTL_RX_FRAME_RAW_NOBLOCK
log_trace( "CAN_DEVCTL_RX_FRAME_RAW_%s: EAGAIN\n",
msg->i.dcmd == CAN_DEVCTL_RX_FRAME_RAW_BLOCK
? "BLOCK" : "NOBLOCK" );

return EAGAIN; /* There are no messages in the queue. */
}

Expand All @@ -1559,6 +1572,8 @@ int io_devctl (resmgr_context_t* ctp, io_devctl_t* msg, RESMGR_OCB_T* _ocb) {
case CAN_DEVCTL_TX_FRAME_RAW: // e.g. cansend -u0,tx0 -w0x1234,1,0xABCD
{
if (_ocb->resmgr->channel_type == RX_CHANNEL) {
log_trace("CAN_DEVCTL_TX_FRAME_RAW: Input/output error\n");

return EIO; // Input/output error
}

Expand Down

0 comments on commit 5085a14

Please sign in to comment.