source: rtems/cpukit/posix/src/mqueuesendsupp.c @ d17c114

Last change on this file since d17c114 was d17c114, checked in by Joel Sherrill <joel.sherrill@…>, on 07/24/08 at 20:43:24

2008-07-24 Joel Sherrill <joel.sherrill@…>

PR 1291/cpukit

  • posix/src/posixtimespecabsolutetimeout.c: New file.
  • itron/inline/rtems/itron/semaphore.inl, itron/src/twai_sem.c, posix/Makefile.am, posix/include/mqueue.h, posix/include/rtems/posix/mqueue.h, posix/include/rtems/posix/semaphore.h, posix/include/rtems/posix/time.h, posix/src/condtimedwait.c, posix/src/mqueuereceive.c, posix/src/mqueuerecvsupp.c, posix/src/mqueuesend.c, posix/src/mqueuesendsupp.c, posix/src/mqueuetimedreceive.c, posix/src/mqueuetimedsend.c, posix/src/mutexfromcorestatus.c, posix/src/mutextimedlock.c, posix/src/semaphorewaitsupp.c, posix/src/semtimedwait.c, posix/src/semtrywait.c, posix/src/semwait.c, rtems/src/semobtain.c, rtems/src/semtranslatereturncode.c, score/include/rtems/score/coresem.h, score/src/coremsgseize.c, score/src/coresemseize.c: This patch addresses issues on implementation of the timeout on the following POSIX services. Some of these services incorrectly took a timeout as a relative time. Others would compute a 0 delta to timeout if the absolute time and the current time were equal and thus incorrectly block the caller forever. The root of the confusion is that POSIX specifies that if the timeout is incorrect (e.g. in the past, is now, or is numerically invalid), that it does not matter if the call would succeed without blocking. This is in contrast to RTEMS programming style where all errors are checked before any critical sections are entered. This fix implemented a more uniform way of handling POSIX absolute time timeouts.

+ pthread_cond_timedwait - could block forever
+ mq_timedreceive - used relative not absolute time
+ mq_timedsend - used relative not absolute time
+ pthread_mutex_timedlock - used relative not absolute time
+ pthread_rwlock_timedrdlock- used relative not absolute time
+ pthread_rwlock_timedwrlock- used relative not absolute time
+ sem_timedwait - could block forever

  • Property mode set to 100644
File size: 3.5 KB
Line 
1/*
2 *  NOTE:  The structure of the routines is identical to that of POSIX
3 *         Message_queues to leave the option of having unnamed message
4 *         queues at a future date.  They are currently not part of the
5 *         POSIX standard but unnamed message_queues are.  This is also
6 *         the reason for the apparently unnecessary tracking of
7 *         the process_shared attribute.  [In addition to the fact that
8 *         it would be trivial to add pshared to the mq_attr structure
9 *         and have process private message queues.]
10 *
11 *         This code ignores the O_RDONLY/O_WRONLY/O_RDWR flag at open
12 *         time.
13 *
14 *  $Id$
15 */
16
17#if HAVE_CONFIG_H
18#include "config.h"
19#endif
20
21#include <stdarg.h>
22
23#include <pthread.h>
24#include <limits.h>
25#include <errno.h>
26#include <fcntl.h>
27#include <mqueue.h>
28
29#include <rtems/system.h>
30#include <rtems/score/watchdog.h>
31#include <rtems/seterr.h>
32#include <rtems/posix/mqueue.h>
33#include <rtems/posix/time.h>
34
35
36/*PAGE
37 *
38 *  _POSIX_Message_queue_Send_support
39 */
40
41int _POSIX_Message_queue_Send_support(
42  mqd_t               mqdes,
43  const char         *msg_ptr,
44  size_t              msg_len,
45  uint32_t            msg_prio,
46  boolean             wait,
47  Watchdog_Interval   timeout
48)
49{
50  POSIX_Message_queue_Control    *the_mq;
51  POSIX_Message_queue_Control_fd *the_mq_fd;
52  Objects_Locations               location;
53  CORE_message_queue_Status       msg_status;
54  boolean                         do_wait;
55
56  /*
57   * Validate the priority.
58   * XXX - Do not validate msg_prio is not less than 0.
59   */
60
61  if ( msg_prio > MQ_PRIO_MAX )
62    rtems_set_errno_and_return_minus_one( EINVAL );
63
64  the_mq_fd = _POSIX_Message_queue_Get_fd( mqdes, &location );
65  switch ( location ) {
66    case OBJECTS_ERROR:
67      rtems_set_errno_and_return_minus_one( EBADF );
68
69    case OBJECTS_REMOTE:
70      _Thread_Dispatch();
71      return POSIX_MP_NOT_IMPLEMENTED();
72      rtems_set_errno_and_return_minus_one( EINVAL );
73
74    case OBJECTS_LOCAL:
75      if ( (the_mq_fd->oflag & O_ACCMODE) == O_RDONLY ) {
76        _Thread_Enable_dispatch();
77        rtems_set_errno_and_return_minus_one( EBADF );
78      }
79
80      the_mq = the_mq_fd->Queue;
81
82      /*
83       *  A timed receive with a bad time will do a poll regardless.
84       */
85      if ( wait )
86        do_wait = (the_mq_fd->oflag & O_NONBLOCK) ? FALSE : TRUE;
87      else
88        do_wait = wait;
89
90      /*
91       *  Now perform the actual message receive
92       */
93      msg_status = _CORE_message_queue_Submit(
94        &the_mq->Message_queue,
95        (void *) msg_ptr,
96        msg_len,
97        mqdes,      /* mqd_t is an object id */
98#if defined(RTEMS_MULTIPROCESSING)
99        NULL,      /* XXX _POSIX_Message_queue_Core_message_queue_mp_support*/
100#else
101        NULL,
102#endif
103        _POSIX_Message_queue_Priority_to_core( msg_prio ),
104        do_wait,
105        timeout    /* no timeout */
106      );
107
108      _Thread_Enable_dispatch();
109
110      /*
111       *  If we had to block, then this is where the task returns
112       *  after it wakes up.  The returned status is correct for
113       *  non-blocking operations but if we blocked, then we need
114       *  to look at the status in our TCB.
115       */
116
117      if ( msg_status == CORE_MESSAGE_QUEUE_STATUS_UNSATISFIED_WAIT )
118        msg_status = _Thread_Executing->Wait.return_code;
119
120      if ( !msg_status )
121        return msg_status;
122
123      rtems_set_errno_and_return_minus_one(
124        _POSIX_Message_queue_Translate_core_message_queue_return_code(
125          msg_status
126        )
127      );
128  }
129  return POSIX_BOTTOM_REACHED();
130}
Note: See TracBrowser for help on using the repository browser.