Avoid a race condition with unsollicited messages

This commit is contained in:
Pierre Pronchery 2014-09-12 00:31:02 +02:00
parent 12f5950036
commit 064cb5f900
3 changed files with 16 additions and 9 deletions

View File

@ -113,8 +113,8 @@ typedef struct _ModemPlugin
#ifdef DEBUG #ifdef DEBUG
static const char * _hayes_command_status[HCS_COUNT] = static const char * _hayes_command_status[HCS_COUNT] =
{ {
"HCS_PENDING", "HCS_QUEUED", "HCS_ACTIVE", "HCS_TIMEOUT", "HCS_ERROR", "HCS_UNKNOWN", "HCS_QUEUED", "HCS_UNKNOWN", "HCS_ACTIVE", "HCS_TIMEOUT",
"HCS_SUCCESS" "HCS_ERROR", "HCS_SUCCESS"
}; };
#endif #endif
@ -1027,11 +1027,11 @@ static int _hayes_parse(Hayes * hayes, HayesChannel * channel)
i++; i++;
continue; continue;
} }
channel->rd_buf[i] = '\0'; channel->rd_buf[i++] = '\0';
if(channel->rd_buf[0] != '\0') if(channel->rd_buf[0] != '\0')
ret |= _parse_do(hayes, channel); ret |= _parse_do(hayes, channel);
channel->rd_buf_cnt -= i; channel->rd_buf_cnt -= i;
memmove(channel->rd_buf, &channel->rd_buf[i + 1], memmove(channel->rd_buf, &channel->rd_buf[i],
channel->rd_buf_cnt); channel->rd_buf_cnt);
i = 0; i = 0;
} }
@ -1249,7 +1249,7 @@ static int _hayes_queue_push(Hayes * hayes, HayesChannel * channel)
#else #else
return 0; /* XXX keep commands in the queue in DATA mode */ return 0; /* XXX keep commands in the queue in DATA mode */
#endif #endif
if(hayes_command_set_status(command, HCS_ACTIVE) != HCS_ACTIVE) if(hayes_command_set_status(command, HCS_PENDING) != HCS_PENDING)
/* no longer push the command */ /* no longer push the command */
return 0; return 0;
attention = hayes_command_get_attention(command); attention = hayes_command_get_attention(command);
@ -2119,8 +2119,9 @@ static HayesCommandStatus _on_reset_settle_callback(HayesCommand * command,
status = _on_request_generic(command, status, hayes); status = _on_request_generic(command, status, hayes);
switch(status) switch(status)
{ {
case HCS_PENDING: /* ignore */ case HCS_UNKNOWN: /* ignore */
case HCS_QUEUED: case HCS_QUEUED:
case HCS_PENDING:
break; break;
case HCS_ACTIVE: /* give it another chance */ case HCS_ACTIVE: /* give it another chance */
break; break;
@ -2288,6 +2289,8 @@ static gboolean _on_watch_can_write(GIOChannel * source, GIOCondition condition,
gpointer data) gpointer data)
{ {
HayesChannel * channel = data; HayesChannel * channel = data;
HayesCommand * command = (channel->queue) != NULL
? channel->queue->data : NULL;
Hayes * hayes = channel->hayes; Hayes * hayes = channel->hayes;
ModemPluginHelper * helper = hayes->helper; ModemPluginHelper * helper = hayes->helper;
gsize cnt = 0; gsize cnt = 0;
@ -2338,6 +2341,8 @@ static gboolean _on_watch_can_write(GIOChannel * source, GIOCondition condition,
if(channel->wr_buf_cnt > 0) /* there is more data to write */ if(channel->wr_buf_cnt > 0) /* there is more data to write */
return TRUE; return TRUE;
channel->wr_source = 0; channel->wr_source = 0;
if(command != NULL)
hayes_command_set_status(command, HCS_ACTIVE);
return FALSE; return FALSE;
} }
@ -2717,8 +2722,9 @@ static HayesCommandStatus _on_request_registration_automatic(
status = _on_request_generic(command, status, priv); status = _on_request_generic(command, status, priv);
switch(status) switch(status)
{ {
case HCS_PENDING: case HCS_UNKNOWN:
case HCS_QUEUED: case HCS_QUEUED:
case HCS_PENDING:
break; break;
case HCS_ACTIVE: case HCS_ACTIVE:
event->registration.mode event->registration.mode

View File

@ -54,7 +54,7 @@ HayesCommand * hayes_command_new(char const * attention)
if((command = object_new(sizeof(*command))) == NULL) if((command = object_new(sizeof(*command))) == NULL)
return NULL; return NULL;
command->priority = HCP_NORMAL; command->priority = HCP_NORMAL;
command->status = HCS_PENDING; command->status = HCS_UNKNOWN;
command->attention = string_new(attention); command->attention = string_new(attention);
command->timeout = 30000; command->timeout = 30000;
command->callback = NULL; command->callback = NULL;

View File

@ -32,8 +32,9 @@ typedef enum _HayesCommandPriority
typedef enum _HayesCommandStatus typedef enum _HayesCommandStatus
{ {
HCS_PENDING = 0, HCS_UNKNOWN = 0,
HCS_QUEUED, HCS_QUEUED,
HCS_PENDING,
HCS_ACTIVE, HCS_ACTIVE,
HCS_TIMEOUT, HCS_TIMEOUT,
HCS_ERROR, HCS_ERROR,