Beispiel #1
0
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 );
}
Beispiel #2
0
int mq_setattr(
  mqd_t                 mqdes,
  const struct mq_attr *mqstat,
  struct mq_attr       *omqstat
)
{
  POSIX_Message_queue_Control_fd *the_mq_fd;
  CORE_message_queue_Control     *the_core_mq;
  Objects_Locations               location;

  if ( !mqstat )
    rtems_set_errno_and_return_minus_one( EINVAL );

  the_mq_fd = _POSIX_Message_queue_Get_fd( mqdes, &location );
  switch ( location ) {

    case OBJECTS_LOCAL:

      the_core_mq = &the_mq_fd->Queue->Message_queue;

      /*
       *  Return the old values.
       */

      if ( omqstat ) {
        omqstat->mq_flags   = the_mq_fd->oflag;
        omqstat->mq_msgsize = the_core_mq->maximum_message_size;
        omqstat->mq_maxmsg  = the_core_mq->maximum_pending_messages;
        omqstat->mq_curmsgs = the_core_mq->number_of_pending_messages;
      }

      the_mq_fd->oflag = mqstat->mq_flags;
      _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 );
}
Beispiel #3
0
int mq_close(
  mqd_t  mqdes
)
{
  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 );
  if ( location == OBJECTS_LOCAL ) {
      /* OBJECTS_LOCAL:
       *
       *  First update the actual message queue to reflect this descriptor
       *  being disassociated.  This may result in the queue being really
       *  deleted.
       */

      the_mq = the_mq_fd->Queue;
      the_mq->open_count -= 1;
      _POSIX_Message_queue_Delete( the_mq );

      /*
       *  Now close this file descriptor.
       */

      _Objects_Close(
        &_POSIX_Message_queue_Information_fds, &the_mq_fd->Object );
      _POSIX_Message_queue_Free_fd( the_mq_fd );

      _Thread_Enable_dispatch();
      return 0;
   }

   /*
    *  OBJECTS_REMOTE:
    *  OBJECTS_ERROR:
    */
   rtems_set_errno_and_return_minus_one( EBADF );
}
ssize_t _POSIX_Message_queue_Receive_support(
  mqd_t               mqdes,
  char               *msg_ptr,
  size_t              msg_len,
  unsigned int       *msg_prio,
  bool                wait,
  Watchdog_Interval   timeout
)
{
  POSIX_Message_queue_Control     *the_mq;
  POSIX_Message_queue_Control_fd  *the_mq_fd;
  Objects_Locations                location;
  size_t                           length_out;
  bool                             do_wait;

  the_mq_fd = _POSIX_Message_queue_Get_fd( mqdes, &location );
  switch ( location ) {

    case OBJECTS_LOCAL:
      if ( (the_mq_fd->oflag & O_ACCMODE) == O_WRONLY ) {
        _Thread_Enable_dispatch();
        rtems_set_errno_and_return_minus_one( EBADF );
      }

      the_mq = the_mq_fd->Queue;

      if ( msg_len < the_mq->Message_queue.maximum_message_size ) {
        _Thread_Enable_dispatch();
        rtems_set_errno_and_return_minus_one( EMSGSIZE );
      }

      /*
       *  Now if something goes wrong, we return a "length" of -1
       *  to indicate an error.
       */

      length_out = -1;

      /*
       *  A timed receive with a bad time will do a poll regardless.
       */
      if ( wait )
        do_wait = (the_mq_fd->oflag & O_NONBLOCK) ? false : true;
      else
        do_wait = wait;

      /*
       *  Now perform the actual message receive
       */
      _CORE_message_queue_Seize(
        &the_mq->Message_queue,
        mqdes,
        msg_ptr,
        &length_out,
        do_wait,
        timeout
      );

      _Thread_Enable_dispatch();
      if (msg_prio) {
        *msg_prio = _POSIX_Message_queue_Priority_from_core(
             _Thread_Executing->Wait.count
          );
      }

      if ( !_Thread_Executing->Wait.return_code )
        return length_out;

      rtems_set_errno_and_return_minus_one(
        _POSIX_Message_queue_Translate_core_message_queue_return_code(
          _Thread_Executing->Wait.return_code
        )
      );

#if defined(RTEMS_MULTIPROCESSING)
    case OBJECTS_REMOTE:
#endif
    case OBJECTS_ERROR:
      break;
  }

  rtems_set_errno_and_return_minus_one( EBADF );
}
Beispiel #5
0
int _POSIX_Message_queue_Send_support(
  mqd_t               mqdes,
  const char         *msg_ptr,
  size_t              msg_len,
  unsigned int        msg_prio,
  bool                wait,
  Watchdog_Interval   timeout
)
{
  POSIX_Message_queue_Control    *the_mq;
  POSIX_Message_queue_Control_fd *the_mq_fd;
  Objects_Locations               location;
  CORE_message_queue_Status       msg_status;
  bool                            do_wait;
  Thread_Control                 *executing;

  /*
   * Validate the priority.
   * XXX - Do not validate msg_prio is not less than 0.
   */

  if ( msg_prio > MQ_PRIO_MAX )
    rtems_set_errno_and_return_minus_one( EINVAL );

  the_mq_fd = _POSIX_Message_queue_Get_fd( mqdes, &location );
  switch ( location ) {

    case OBJECTS_LOCAL:
      if ( (the_mq_fd->oflag & O_ACCMODE) == O_RDONLY ) {
        _Objects_Put( &the_mq_fd->Object );
        rtems_set_errno_and_return_minus_one( EBADF );
      }

      the_mq = the_mq_fd->Queue;

      /*
       *  A timed receive with a bad time will do a poll regardless.
       */
      if ( wait )
        do_wait = (the_mq_fd->oflag & O_NONBLOCK) ? false : true;
      else
        do_wait = wait;

      /*
       *  Now perform the actual message receive
       */
      executing = _Thread_Executing;
      msg_status = _CORE_message_queue_Submit(
        &the_mq->Message_queue,
        executing,
        msg_ptr,
        msg_len,
        mqdes,      /* mqd_t is an object id */
        NULL,
        _POSIX_Message_queue_Priority_to_core( msg_prio ),
        do_wait,
        timeout    /* no timeout */
      );

      _Objects_Put( &the_mq_fd->Object );

      /*
       *  If we had to block, then this is where the task returns
       *  after it wakes up.  The returned status is correct for
       *  non-blocking operations but if we blocked, then we need
       *  to look at the status in our TCB.
       */

      if ( msg_status == CORE_MESSAGE_QUEUE_STATUS_UNSATISFIED_WAIT )
        msg_status = executing->Wait.return_code;

      if ( !msg_status )
        return msg_status;

      rtems_set_errno_and_return_minus_one(
        _POSIX_Message_queue_Translate_core_message_queue_return_code(
          msg_status
        )
      );

#if defined(RTEMS_MULTIPROCESSING)
    case OBJECTS_REMOTE:
#endif
    case OBJECTS_ERROR:
      break;
  }

  rtems_set_errno_and_return_minus_one( EBADF );
}