Ejemplo n.º 1
0
void _POSIX_Message_queue_Delete(
  POSIX_Message_queue_Control *the_mq
)
{
  if ( !the_mq->linked && !the_mq->open_count ) {
      Objects_Control *the_object = &the_mq->Object;

      #if defined(RTEMS_DEBUG)
        /*
         *  the name memory will have been freed by unlink.
         */
	if ( the_object->name.name_p ) {
          printk(
            "POSIX MQ name (%p) not freed by unlink\n",
	    (void *)the_object->name.name_p
          );
	  _Workspace_Free( (void *)the_object->name.name_p );
        }
      #endif

      _Objects_Close( &_POSIX_Message_queue_Information, the_object );

      _CORE_message_queue_Close(
        &the_mq->Message_queue,
        NULL,        /* no MP support */
        CORE_MESSAGE_QUEUE_STATUS_WAS_DELETED
      );

    _POSIX_Message_queue_Free( the_mq );

  }
}
Ejemplo n.º 2
0
int _POSIX_Message_queue_Create_support(
  const char                    *name,
  int                            pshared,
  unsigned int                   oflag,
  struct mq_attr                *attr_ptr,
  POSIX_Message_queue_Control  **message_queue
)
{
  POSIX_Message_queue_Control   *the_mq;
  CORE_message_queue_Attributes *the_mq_attr;
  struct mq_attr                 attr;

  _Thread_Disable_dispatch();
 
  /*
   *  There is no real basis for the default values.  They will work
   *  but were not compared against any existing implementation for
   *  compatibility.  See README.mqueue for an example program we
   *  think will print out the defaults.  Report anything you find with it.
   */

  if ( attr_ptr == NULL ) {
    attr.mq_maxmsg  = 10;
    attr.mq_msgsize = 16;
  } else {
    if ( attr_ptr->mq_maxmsg < 0 ){
      _Thread_Enable_dispatch();
      set_errno_and_return_minus_one( EINVAL );
    }

    if ( attr_ptr->mq_msgsize < 0 ){
      _Thread_Enable_dispatch();
      set_errno_and_return_minus_one( EINVAL );
    }

    attr = *attr_ptr;
  }

#if 0 && defined(RTEMS_MULTIPROCESSING)
  if ( pshared == PTHREAD_PROCESS_SHARED &&
       !( _Objects_MP_Allocate_and_open( &_POSIX_Message_queue_Information, 0,
                            the_mq->Object.id, FALSE ) ) ) {
    _POSIX_Message_queue_Free( the_mq );
    _Thread_Enable_dispatch();
    set_errno_and_return_minus_one( ENFILE );
  }
#endif
 
  the_mq = _POSIX_Message_queue_Allocate();
  if ( !the_mq ) {
    _Thread_Enable_dispatch();
    set_errno_and_return_minus_one( ENFILE );
  }
 
  the_mq->process_shared  = pshared;
  the_mq->oflag = oflag;
  the_mq->named = TRUE;
  the_mq->open_count = 1;
  the_mq->linked = TRUE;

 
  /* XXX
   *
   *  Note that thread blocking discipline should be based on the
   *  current scheduling policy.
   */

  the_mq_attr = &the_mq->Message_queue.Attributes;
  the_mq_attr->discipline = CORE_MESSAGE_QUEUE_DISCIPLINES_FIFO;

  if ( ! _CORE_message_queue_Initialize(
           &the_mq->Message_queue,
           OBJECTS_POSIX_MESSAGE_QUEUES,
           the_mq_attr,
           attr.mq_maxmsg,
           attr.mq_msgsize,
#if 0 && defined(RTEMS_MULTIPROCESSING)
           _POSIX_Message_queue_MP_Send_extract_proxy
#else
           NULL
#endif
      ) ) {

#if 0 && defined(RTEMS_MULTIPROCESSING)
    if ( pshared == PTHREAD_PROCESS_SHARED )
      _Objects_MP_Close( &_POSIX_Message_queue_Information, the_mq->Object.id );
#endif
 
    _POSIX_Message_queue_Free( the_mq );
    _Thread_Enable_dispatch();
    set_errno_and_return_minus_one( ENOSPC );
  }

  _Objects_Open(
    &_POSIX_Message_queue_Information,
    &the_mq->Object,
    (char *) name
  );
 
  *message_queue = the_mq;
 
#if 0 && defined(RTEMS_MULTIPROCESSING)
  if ( pshared == PTHREAD_PROCESS_SHARED )
    _POSIX_Message_queue_MP_Send_process_packet(
      POSIX_MESSAGE_QUEUE_MP_ANNOUNCE_CREATE,
      the_mq->Object.id,
      (char *) name,
      0                          /* Not used */
    );
#endif
 
  _Thread_Enable_dispatch();
  return 0;
}
Ejemplo n.º 3
0
static mqd_t _POSIX_Message_queue_Create(
  const char           *name_arg,
  size_t                name_len,
  int                   oflag,
  const struct mq_attr *attr
)
{
  POSIX_Message_queue_Control  *the_mq;
  char                         *name;

  /* length of name has already been validated */

  if ( attr->mq_maxmsg <= 0 ){
    rtems_set_errno_and_return_value( EINVAL, MQ_OPEN_FAILED );
  }

  if ( attr->mq_msgsize <= 0 ){
    rtems_set_errno_and_return_value( EINVAL, MQ_OPEN_FAILED );
  }

  the_mq = _POSIX_Message_queue_Allocate_unprotected();
  if ( !the_mq ) {
    rtems_set_errno_and_return_value( ENFILE, MQ_OPEN_FAILED );
  }

  /*
   * Make a copy of the user's string for name just in case it was
   * dynamically constructed.
   */
  name = _Workspace_String_duplicate( name_arg, name_len );
  if ( !name ) {
    _POSIX_Message_queue_Free( the_mq );
    rtems_set_errno_and_return_value( ENOMEM, MQ_OPEN_FAILED );
  }

  the_mq->open_count = 1;
  the_mq->linked = true;
  the_mq->oflag = oflag;

  /*
   *  NOTE: That thread blocking discipline should be based on the
   *  current scheduling policy.
   *
   *  Joel: Cite POSIX or OpenGroup on above statement so we can determine
   *        if it is a real requirement.
   */
  if (
    !_CORE_message_queue_Initialize(
      &the_mq->Message_queue,
      CORE_MESSAGE_QUEUE_DISCIPLINES_FIFO,
      attr->mq_maxmsg,
      attr->mq_msgsize
    )
  ) {
    _POSIX_Message_queue_Free( the_mq );
    _Workspace_Free( name );
    rtems_set_errno_and_return_value( ENOSPC, MQ_OPEN_FAILED );
  }

  _Objects_Open_string(
    &_POSIX_Message_queue_Information,
    &the_mq->Object,
    name
  );
  return the_mq->Object.id;
}
Ejemplo n.º 4
0
int _POSIX_Message_queue_Create_support(
  const char                    *name_arg,
  size_t                         name_len,
  int                            pshared,
  struct mq_attr                *attr_ptr,
  POSIX_Message_queue_Control  **message_queue
)
{
  POSIX_Message_queue_Control   *the_mq;
  CORE_message_queue_Attributes *the_mq_attr;
  struct mq_attr                 attr;
  char                          *name;

  /* length of name has already been validated */

  _Thread_Disable_dispatch();

  /*
   *  There is no real basis for the default values.  They will work
   *  but were not compared against any existing implementation for
   *  compatibility.  See README.mqueue for an example program we
   *  think will print out the defaults.  Report anything you find with it.
   */
  if ( attr_ptr == NULL ) {
    attr.mq_maxmsg  = 10;
    attr.mq_msgsize = 16;
  } else {
    if ( attr_ptr->mq_maxmsg <= 0 ){
      _Thread_Enable_dispatch();
      rtems_set_errno_and_return_minus_one( EINVAL );
    }

    if ( attr_ptr->mq_msgsize <= 0 ){
      _Thread_Enable_dispatch();
      rtems_set_errno_and_return_minus_one( EINVAL );
    }

    attr = *attr_ptr;
  }

  the_mq = _POSIX_Message_queue_Allocate();
  if ( !the_mq ) {
    _Thread_Enable_dispatch();
    rtems_set_errno_and_return_minus_one( ENFILE );
  }

  /*
   * Make a copy of the user's string for name just in case it was
   * dynamically constructed.
   */
  name = _Workspace_String_duplicate( name_arg, name_len );
  if ( !name ) {
    _POSIX_Message_queue_Free( the_mq );
    _Thread_Enable_dispatch();
    rtems_set_errno_and_return_minus_one( ENOMEM );
  }

  the_mq->process_shared  = pshared;
  the_mq->named = true;
  the_mq->open_count = 1;
  the_mq->linked = true;

  /*
   *  NOTE: That thread blocking discipline should be based on the
   *  current scheduling policy.
   *
   *  Joel: Cite POSIX or OpenGroup on above statement so we can determine
   *        if it is a real requirement.
   */
  the_mq_attr = &the_mq->Message_queue.Attributes;
  the_mq_attr->discipline = CORE_MESSAGE_QUEUE_DISCIPLINES_FIFO;

  if ( !_CORE_message_queue_Initialize(
           &the_mq->Message_queue,
           the_mq_attr,
           attr.mq_maxmsg,
           attr.mq_msgsize
      ) ) {

    _POSIX_Message_queue_Free( the_mq );
    _Workspace_Free(name);
    _Thread_Enable_dispatch();
    rtems_set_errno_and_return_minus_one( ENOSPC );
  }

  _Objects_Open_string(
    &_POSIX_Message_queue_Information,
    &the_mq->Object,
    name
  );

  *message_queue = the_mq;

  _Thread_Enable_dispatch();
  return 0;
}