int mq_notify( mqd_t mqdes, const struct sigevent *notification ) { POSIX_Message_queue_Control *the_mq; POSIX_Message_queue_Control_fd *the_mq_fd; Objects_Locations location; the_mq_fd = _POSIX_Message_queue_Get_fd( mqdes, &location ); switch ( location ) { case OBJECTS_LOCAL: the_mq = the_mq_fd->Queue; if ( notification ) { if ( _CORE_message_queue_Is_notify_enabled( &the_mq->Message_queue ) ) { _Thread_Enable_dispatch(); rtems_set_errno_and_return_minus_one( EBUSY ); } _CORE_message_queue_Set_notify( &the_mq->Message_queue, NULL, NULL ); the_mq->notification = *notification; _CORE_message_queue_Set_notify( &the_mq->Message_queue, _POSIX_Message_queue_Notify_handler, the_mq ); } else { _CORE_message_queue_Set_notify( &the_mq->Message_queue, NULL, NULL ); } _Thread_Enable_dispatch(); return 0; #if defined(RTEMS_MULTIPROCESSING) case OBJECTS_REMOTE: #endif case OBJECTS_ERROR: break; } rtems_set_errno_and_return_minus_one( EBADF ); }
void _POSIX_Message_queue_Notify_handler( void *user_data ) { POSIX_Message_queue_Control *the_mq; the_mq = user_data; kill( getpid(), the_mq->notification.sigev_signo ); _CORE_message_queue_Set_notify( &the_mq->Message_queue, NULL, NULL ); }
bool _CORE_message_queue_Initialize( CORE_message_queue_Control *the_message_queue, CORE_message_queue_Attributes *the_message_queue_attributes, uint32_t maximum_pending_messages, size_t maximum_message_size ) { size_t message_buffering_required; size_t allocated_message_size; the_message_queue->maximum_pending_messages = maximum_pending_messages; the_message_queue->number_of_pending_messages = 0; the_message_queue->maximum_message_size = maximum_message_size; _CORE_message_queue_Set_notify( the_message_queue, NULL, NULL ); /* * Round size up to multiple of a pointer for chain init and * check for overflow on adding overhead to each message. */ allocated_message_size = maximum_message_size; if (allocated_message_size & (sizeof(uint32_t) - 1)) { allocated_message_size += sizeof(uint32_t); allocated_message_size &= ~(sizeof(uint32_t) - 1); } if (allocated_message_size < maximum_message_size) return false; /* * Calculate how much total memory is required for message buffering and * check for overflow on the multiplication. */ message_buffering_required = (size_t) maximum_pending_messages * (allocated_message_size + sizeof(CORE_message_queue_Buffer_control)); if (message_buffering_required < allocated_message_size) return false; /* * Attempt to allocate the message memory */ the_message_queue->message_buffers = (CORE_message_queue_Buffer *) _Workspace_Allocate( message_buffering_required ); if (the_message_queue->message_buffers == 0) return false; /* * Initialize the pool of inactive messages, pending messages, * and set of waiting threads. */ _Chain_Initialize ( &the_message_queue->Inactive_messages, the_message_queue->message_buffers, (size_t) maximum_pending_messages, allocated_message_size + sizeof( CORE_message_queue_Buffer_control ) ); _Chain_Initialize_empty( &the_message_queue->Pending_messages ); _Thread_queue_Initialize( &the_message_queue->Wait_queue, _CORE_message_queue_Is_priority( the_message_queue_attributes ) ? THREAD_QUEUE_DISCIPLINE_PRIORITY : THREAD_QUEUE_DISCIPLINE_FIFO, STATES_WAITING_FOR_MESSAGE, CORE_MESSAGE_QUEUE_STATUS_TIMEOUT ); return true; }
bool _CORE_message_queue_Initialize( CORE_message_queue_Control *the_message_queue, CORE_message_queue_Attributes *the_message_queue_attributes, uint32_t maximum_pending_messages, size_t maximum_message_size ) { size_t message_buffering_required = 0; size_t allocated_message_size; the_message_queue->maximum_pending_messages = maximum_pending_messages; the_message_queue->number_of_pending_messages = 0; the_message_queue->maximum_message_size = maximum_message_size; _CORE_message_queue_Set_notify( the_message_queue, NULL, NULL ); allocated_message_size = maximum_message_size; /* * Check if allocated_message_size is aligned to uintptr-size boundary. * If not, it will increase allocated_message_size to multiplicity of pointer * size. */ if (allocated_message_size & (sizeof(uintptr_t) - 1)) { allocated_message_size += sizeof(uintptr_t); allocated_message_size &= ~(sizeof(uintptr_t) - 1); } /* * Check for an overflow. It can occur while increasing allocated_message_size * to multiplicity of uintptr_t above. */ if (allocated_message_size < maximum_message_size) return false; /* * Calculate how much total memory is required for message buffering and * check for overflow on the multiplication. */ if ( !size_t_mult32_with_overflow( (size_t) maximum_pending_messages, allocated_message_size + sizeof(CORE_message_queue_Buffer_control), &message_buffering_required ) ) return false; /* * Attempt to allocate the message memory */ the_message_queue->message_buffers = (CORE_message_queue_Buffer *) _Workspace_Allocate( message_buffering_required ); if (the_message_queue->message_buffers == 0) return false; /* * Initialize the pool of inactive messages, pending messages, * and set of waiting threads. */ _Chain_Initialize ( &the_message_queue->Inactive_messages, the_message_queue->message_buffers, (size_t) maximum_pending_messages, allocated_message_size + sizeof( CORE_message_queue_Buffer_control ) ); _Chain_Initialize_empty( &the_message_queue->Pending_messages ); _Thread_queue_Initialize( &the_message_queue->Wait_queue, _CORE_message_queue_Is_priority( the_message_queue_attributes ) ? THREAD_QUEUE_DISCIPLINE_PRIORITY : THREAD_QUEUE_DISCIPLINE_FIFO, STATES_WAITING_FOR_MESSAGE, CORE_MESSAGE_QUEUE_STATUS_TIMEOUT ); return true; }
bool _CORE_message_queue_Initialize( CORE_message_queue_Control *the_message_queue, CORE_message_queue_Disciplines discipline, uint32_t maximum_pending_messages, size_t maximum_message_size ) { size_t message_buffering_required = 0; size_t aligned_message_size; size_t align_mask; the_message_queue->maximum_pending_messages = maximum_pending_messages; the_message_queue->number_of_pending_messages = 0; the_message_queue->maximum_message_size = maximum_message_size; _CORE_message_queue_Set_notify( the_message_queue, NULL ); /* * Align up the maximum message size to be an integral multiple of the * pointer size. */ align_mask = sizeof(uintptr_t) - 1; aligned_message_size = ( maximum_message_size + align_mask ) & ~align_mask; /* * Check for an integer overflow. It can occur while aligning up the maximum * message size. */ if (aligned_message_size < maximum_message_size) return false; /* * Calculate how much total memory is required for message buffering and * check for overflow on the multiplication. */ if ( !size_t_mult32_with_overflow( (size_t) maximum_pending_messages, aligned_message_size + sizeof(CORE_message_queue_Buffer_control), &message_buffering_required ) ) return false; /* * Attempt to allocate the message memory */ the_message_queue->message_buffers = (CORE_message_queue_Buffer *) _Workspace_Allocate( message_buffering_required ); if (the_message_queue->message_buffers == 0) return false; /* * Initialize the pool of inactive messages, pending messages, * and set of waiting threads. */ _Chain_Initialize ( &the_message_queue->Inactive_messages, the_message_queue->message_buffers, (size_t) maximum_pending_messages, aligned_message_size + sizeof( CORE_message_queue_Buffer_control ) ); _Chain_Initialize_empty( &the_message_queue->Pending_messages ); _Thread_queue_Initialize( &the_message_queue->Wait_queue ); if ( discipline == CORE_MESSAGE_QUEUE_DISCIPLINES_PRIORITY ) { the_message_queue->operations = &_Thread_queue_Operations_priority; } else { the_message_queue->operations = &_Thread_queue_Operations_FIFO; } return true; }