mirror of
https://gitlab.rtems.org/rtems/rtos/rtems.git
synced 2025-11-16 12:34:45 +00:00
2001-08-09 Joel Sherrill <joel@OARcorp.com>
* c/src/exec/itron/src/snd_mbx.c, c/src/exec/itron/src/tsnd_mbf.c c/src/exec/posix/src/mqueuesendsupp.c, c/src/exec/rtems/src/msgqsubmit.c, c/src/exec/score/include/rtems/score/coremsg.h, c/src/exec/score/inline/rtems/score/coremsg.inl, c/src/exec/score/src/coremsgsubmit.c: Unblocking message queue operations should NOT use _Thread_Executing for return status since it is permissible to invoke message send operations from an ISR. This was reported by Suvrat Gupta <suvrat@utstar.com>.
This commit is contained in:
@@ -29,6 +29,7 @@ ER snd_msg(
|
||||
Objects_Locations location;
|
||||
unsigned32 message_priority;
|
||||
void *message_contents;
|
||||
CORE_message_queue_Status msg_status;
|
||||
|
||||
if ( !pk_msg )
|
||||
return E_PAR;
|
||||
@@ -46,7 +47,7 @@ ER snd_msg(
|
||||
message_priority = CORE_MESSAGE_QUEUE_SEND_REQUEST;
|
||||
|
||||
message_contents = pk_msg;
|
||||
_CORE_message_queue_Submit(
|
||||
msg_status = _CORE_message_queue_Submit(
|
||||
&the_mailbox->message_queue,
|
||||
&message_contents,
|
||||
sizeof(T_MSG *),
|
||||
@@ -60,8 +61,6 @@ ER snd_msg(
|
||||
}
|
||||
|
||||
_ITRON_return_errorno(
|
||||
_ITRON_Mailbox_Translate_core_message_queue_return_code(
|
||||
_Thread_Executing->Wait.return_code
|
||||
)
|
||||
_ITRON_Mailbox_Translate_core_message_queue_return_code( msg_status )
|
||||
);
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@ ER tsnd_mbf(
|
||||
Objects_Locations location;
|
||||
Watchdog_Interval interval;
|
||||
boolean wait;
|
||||
CORE_message_queue_Status msg_status;
|
||||
|
||||
if (msgsz <= 0 || !msg)
|
||||
return E_PAR;
|
||||
@@ -57,7 +58,7 @@ ER tsnd_mbf(
|
||||
|
||||
case OBJECTS_LOCAL:
|
||||
/* XXX Submit needs to take into account blocking */
|
||||
_CORE_message_queue_Submit(
|
||||
msg_status = _CORE_message_queue_Submit(
|
||||
&the_message_buffer->message_queue,
|
||||
msg,
|
||||
msgsz,
|
||||
@@ -69,7 +70,7 @@ ER tsnd_mbf(
|
||||
);
|
||||
_Thread_Enable_dispatch();
|
||||
return _ITRON_Message_buffer_Translate_core_message_buffer_return_code(
|
||||
_Thread_Executing->Wait.return_code
|
||||
msg_status
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -44,6 +44,7 @@ int _POSIX_Message_queue_Send_support(
|
||||
{
|
||||
register POSIX_Message_queue_Control *the_mq;
|
||||
Objects_Locations location;
|
||||
CORE_message_queue_Status msg_status;
|
||||
|
||||
/*
|
||||
* Validate the priority.
|
||||
@@ -70,7 +71,7 @@ int _POSIX_Message_queue_Send_support(
|
||||
set_errno_and_return_minus_one( EBADF );
|
||||
}
|
||||
|
||||
_CORE_message_queue_Submit(
|
||||
msg_status = _CORE_message_queue_Submit(
|
||||
&the_mq->Message_queue,
|
||||
(void *) msg_ptr,
|
||||
msg_len,
|
||||
@@ -86,12 +87,12 @@ int _POSIX_Message_queue_Send_support(
|
||||
);
|
||||
|
||||
_Thread_Enable_dispatch();
|
||||
if ( !_Thread_Executing->Wait.return_code )
|
||||
if ( !msg_status )
|
||||
return 0;
|
||||
|
||||
set_errno_and_return_minus_one(
|
||||
_POSIX_Message_queue_Translate_core_message_queue_return_code(
|
||||
_Thread_Executing->Wait.return_code
|
||||
msg_status
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -61,6 +61,7 @@ rtems_status_code _Message_queue_Submit(
|
||||
{
|
||||
register Message_queue_Control *the_message_queue;
|
||||
Objects_Locations location;
|
||||
CORE_message_queue_Status msg_status;
|
||||
|
||||
the_message_queue = _Message_queue_Get( id, &location );
|
||||
switch ( location )
|
||||
@@ -97,7 +98,7 @@ rtems_status_code _Message_queue_Submit(
|
||||
case OBJECTS_LOCAL:
|
||||
switch ( submit_type ) {
|
||||
case MESSAGE_QUEUE_SEND_REQUEST:
|
||||
_CORE_message_queue_Send(
|
||||
msg_status = _CORE_message_queue_Send(
|
||||
&the_message_queue->message_queue,
|
||||
buffer,
|
||||
size,
|
||||
@@ -112,7 +113,7 @@ rtems_status_code _Message_queue_Submit(
|
||||
);
|
||||
break;
|
||||
case MESSAGE_QUEUE_URGENT_REQUEST:
|
||||
_CORE_message_queue_Urgent(
|
||||
msg_status = _CORE_message_queue_Urgent(
|
||||
&the_message_queue->message_queue,
|
||||
buffer,
|
||||
size,
|
||||
@@ -131,9 +132,8 @@ rtems_status_code _Message_queue_Submit(
|
||||
}
|
||||
|
||||
_Thread_Enable_dispatch();
|
||||
return _Message_queue_Translate_core_message_queue_return_code(
|
||||
_Thread_Executing->Wait.return_code
|
||||
);
|
||||
return
|
||||
_Message_queue_Translate_core_message_queue_return_code( msg_status );
|
||||
|
||||
}
|
||||
return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */
|
||||
|
||||
@@ -239,7 +239,7 @@ CORE_message_queue_Status _CORE_message_queue_Broadcast(
|
||||
*
|
||||
*/
|
||||
|
||||
void _CORE_message_queue_Submit(
|
||||
CORE_message_queue_Status _CORE_message_queue_Submit(
|
||||
CORE_message_queue_Control *the_message_queue,
|
||||
void *buffer,
|
||||
unsigned32 size,
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
* This routine sends a message to the end of the specified message queue.
|
||||
*/
|
||||
|
||||
RTEMS_INLINE_ROUTINE void _CORE_message_queue_Send(
|
||||
RTEMS_INLINE_ROUTINE CORE_message_queue_Status _CORE_message_queue_Send(
|
||||
CORE_message_queue_Control *the_message_queue,
|
||||
void *buffer,
|
||||
unsigned32 size,
|
||||
@@ -37,7 +37,7 @@ RTEMS_INLINE_ROUTINE void _CORE_message_queue_Send(
|
||||
Watchdog_Interval timeout
|
||||
)
|
||||
{
|
||||
_CORE_message_queue_Submit(
|
||||
return _CORE_message_queue_Submit(
|
||||
the_message_queue,
|
||||
buffer,
|
||||
size,
|
||||
@@ -62,7 +62,7 @@ RTEMS_INLINE_ROUTINE void _CORE_message_queue_Send(
|
||||
* This routine sends a message to the front of the specified message queue.
|
||||
*/
|
||||
|
||||
RTEMS_INLINE_ROUTINE void _CORE_message_queue_Urgent(
|
||||
RTEMS_INLINE_ROUTINE CORE_message_queue_Status _CORE_message_queue_Urgent(
|
||||
CORE_message_queue_Control *the_message_queue,
|
||||
void *buffer,
|
||||
unsigned32 size,
|
||||
@@ -72,7 +72,7 @@ RTEMS_INLINE_ROUTINE void _CORE_message_queue_Urgent(
|
||||
Watchdog_Interval timeout
|
||||
)
|
||||
{
|
||||
_CORE_message_queue_Submit(
|
||||
return _CORE_message_queue_Submit(
|
||||
the_message_queue,
|
||||
buffer,
|
||||
size,
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
* error code - if unsuccessful
|
||||
*/
|
||||
|
||||
void _CORE_message_queue_Submit(
|
||||
CORE_message_queue_Status _CORE_message_queue_Submit(
|
||||
CORE_message_queue_Control *the_message_queue,
|
||||
void *buffer,
|
||||
unsigned32 size,
|
||||
@@ -67,14 +67,9 @@ void _CORE_message_queue_Submit(
|
||||
ISR_Level level;
|
||||
CORE_message_queue_Buffer_control *the_message;
|
||||
Thread_Control *the_thread;
|
||||
Thread_Control *executing;
|
||||
|
||||
_Thread_Executing->Wait.return_code = CORE_MESSAGE_QUEUE_STATUS_SUCCESSFUL;
|
||||
|
||||
if ( size > the_message_queue->maximum_message_size ) {
|
||||
_Thread_Executing->Wait.return_code =
|
||||
CORE_MESSAGE_QUEUE_STATUS_INVALID_SIZE;
|
||||
return;
|
||||
return CORE_MESSAGE_QUEUE_STATUS_INVALID_SIZE;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -96,7 +91,7 @@ void _CORE_message_queue_Submit(
|
||||
if ( !_Objects_Is_local_id( the_thread->Object.id ) )
|
||||
(*api_message_queue_mp_support) ( the_thread, id );
|
||||
#endif
|
||||
return;
|
||||
return CORE_MESSAGE_QUEUE_STATUS_SUCCESSFUL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -114,10 +109,9 @@ void _CORE_message_queue_Submit(
|
||||
/*
|
||||
* NOTE: If the system is consistent, this error should never occur.
|
||||
*/
|
||||
|
||||
if ( !the_message ) {
|
||||
_Thread_Executing->Wait.return_code =
|
||||
CORE_MESSAGE_QUEUE_STATUS_UNSATISFIED;
|
||||
return;
|
||||
return CORE_MESSAGE_QUEUE_STATUS_UNSATISFIED;
|
||||
}
|
||||
|
||||
_CORE_message_queue_Copy_buffer(
|
||||
@@ -133,7 +127,7 @@ void _CORE_message_queue_Submit(
|
||||
the_message,
|
||||
submit_type
|
||||
);
|
||||
return;
|
||||
return CORE_MESSAGE_QUEUE_STATUS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -143,20 +137,39 @@ void _CORE_message_queue_Submit(
|
||||
*/
|
||||
|
||||
if ( !wait ) {
|
||||
_Thread_Executing->Wait.return_code = CORE_MESSAGE_QUEUE_STATUS_TOO_MANY;
|
||||
return;
|
||||
return CORE_MESSAGE_QUEUE_STATUS_TOO_MANY;
|
||||
}
|
||||
|
||||
executing = _Thread_Executing;
|
||||
/*
|
||||
* Do NOT block on a send if the caller is in an ISR. It is
|
||||
* deadly to block in an ISR.
|
||||
*/
|
||||
|
||||
_ISR_Disable( level );
|
||||
_Thread_queue_Enter_critical_section( &the_message_queue->Wait_queue );
|
||||
executing->Wait.queue = &the_message_queue->Wait_queue;
|
||||
executing->Wait.id = id;
|
||||
executing->Wait.return_argument = (void *)buffer;
|
||||
executing->Wait.return_argument_1 = (void *)size;
|
||||
executing->Wait.count = submit_type;
|
||||
_ISR_Enable( level );
|
||||
if ( _ISR_Is_in_progress() ) {
|
||||
return CORE_MESSAGE_QUEUE_STATUS_UNSATISFIED;
|
||||
}
|
||||
|
||||
_Thread_queue_Enqueue( &the_message_queue->Wait_queue, timeout );
|
||||
/*
|
||||
* WARNING!! executing should NOT be used prior to this point.
|
||||
* Thus the unusual choice to open a new scope and declare
|
||||
* it as a variable. Doing this emphasizes how dangerous it
|
||||
* would be to use this variable prior to here.
|
||||
*/
|
||||
|
||||
{
|
||||
Thread_Control *executing = _Thread_Executing;
|
||||
|
||||
_ISR_Disable( level );
|
||||
_Thread_queue_Enter_critical_section( &the_message_queue->Wait_queue );
|
||||
executing->Wait.queue = &the_message_queue->Wait_queue;
|
||||
executing->Wait.id = id;
|
||||
executing->Wait.return_argument = (void *)buffer;
|
||||
executing->Wait.return_argument_1 = (void *)size;
|
||||
executing->Wait.count = submit_type;
|
||||
_ISR_Enable( level );
|
||||
|
||||
_Thread_queue_Enqueue( &the_message_queue->Wait_queue, timeout );
|
||||
}
|
||||
|
||||
return CORE_MESSAGE_QUEUE_STATUS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user