Mercurial > nand-ecoscentric
changeset 492:c8a05a94076e
* doc/posix.sgml: Document them.
* src/mqueue.cxx (mq_timedreceive): Make fully compliant by dealing
with bogus timeouts.
(mq_timedsend): Ditto.
* src/mqueue.cxx (mq_timedsend): New function. Implementing POSIX
1003.1d draft definition.
(mq_timedreceive): Ditto.
| author | jlarmour |
|---|---|
| date | Mon, 13 Jan 2003 05:49:42 +0000 |
| parents | def85e4d96d2 |
| children | 413246fac734 |
| files | packages/compat/posix/current/ChangeLog packages/compat/posix/current/doc/posix.sgml packages/compat/posix/current/src/mqueue.cxx |
| diffstat | 3 files changed, 206 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- a/packages/compat/posix/current/ChangeLog +++ b/packages/compat/posix/current/ChangeLog @@ -1,3 +1,17 @@ +2003-01-13 Jonathan Larmour <jifl@eCosCentric.com> + + * doc/posix.sgml: Document them. + + * src/mqueue.cxx (mq_timedreceive): Make fully compliant by dealing + with bogus timeouts. + (mq_timedsend): Ditto. + +2003-01-13 Dmitriy Korovkin <dkorovkin@rambler.ru> + + * src/mqueue.cxx (mq_timedsend): New function. Implementing POSIX + 1003.1d draft definition. + (mq_timedreceive): Ditto. + 2002-12-10 Wade Jensen <waj4news@cox.net> 2002-12-10 Jonathan Larmour <jifl@eCosCentric.com>
--- a/packages/compat/posix/current/doc/posix.sgml +++ b/packages/compat/posix/current/doc/posix.sgml @@ -1116,6 +1116,15 @@ int mq_setattr( mqd_t mqde int mq_getattr( mqd_t mqdes, struct mq_attr *mqstat ); int mq_notify( mqd_t mqdes, const struct sigevent *notification ); </screen> +<para>From POSIX 1003.1d draft: </para> +<screen> +int mq_send( mqd_t mqdes, const char *msg_ptr, + size_t msg_len, unsigned int msg_prio, + const struct timespec *abs_timeout ); +ssize_t mq_receive( mqd_t mqdes, char *msg_ptr, + size_t msg_len, unsigned int *msg_prio, + const struct timespec *abs_timeout ); +</screen> </sect2> <!-- =================================================================== -->
--- a/packages/compat/posix/current/src/mqueue.cxx +++ b/packages/compat/posix/current/src/mqueue.cxx @@ -84,7 +84,10 @@ # include <signal.h> # include "pprivate.h" // cyg_sigqueue() #endif - +#ifdef CYGFUN_KERNEL_THREADS_TIMER +# include <time.h> +# include "pprivate.h" // cyg_timespec_to_ticks() +#endif /* CONSTANTS */ @@ -671,7 +674,186 @@ mq_receive( mqd_t mqdes, char *msg_ptr, } // mq_receive() + //------------------------------------------------------------------------ +#ifdef CYGFUN_KERNEL_THREADS_TIMER +externC int +mq_timedsend( mqd_t mqdes, const char *msg_ptr, size_t msg_len, + unsigned int msg_prio, const struct timespec *abs_timeout) +{ + CYG_REPORT_FUNCTYPE( "returning %d" ); + CYG_REPORT_FUNCARG6( "mqdes=%08x, msg_ptr=%08x, msg_len=%u, msg_prio=%u, + abs_timeout = %lu, %ld", + mqdes, msg_ptr, msg_len, msg_prio, + abs_timeout->tv_sec, abs_timeout->tv_nsec); + CYG_CHECK_DATA_PTRC( msg_ptr ); + + struct mquser *user = (struct mquser *)mqdes; + struct mqtabent *tabent = user->tabent; + +#ifdef CYGIMP_POSIX_MQUEUE_VALIDATE_DESCRIPTOR + if ( user->magic != MQ_VALID_MAGIC ) { + errno = EBADF; + CYG_REPORT_RETVAL( -1 ); + return -1; + } +#endif + + if ( msg_len > (size_t)tabent->msgsize ) { + errno = EMSGSIZE; + CYG_REPORT_RETVAL( -1 ); + return -1; + } + + if ( msg_prio > MQ_PRIO_MAX ) { + errno = EINVAL; + CYG_REPORT_RETVAL( -1 ); + return -1; + } + + if ( (O_WRONLY != (user->flags & O_WRONLY)) && + (O_RDWR != (user->flags & O_RDWR)) ) { + errno = EBADF; + CYG_REPORT_RETVAL( -1 ); + return -1; + } + + // go for it + Cyg_Mqueue::qerr_t err; + bool nonblocking = ((user->flags & O_NONBLOCK) == O_NONBLOCK); + bool badtimespec = (abs_timeout->tv_nsec < 0) || + (abs_timeout->tv_nsec > 999999999l); + err = tabent->mq->put( msg_ptr, msg_len, msg_prio, + !nonblocking && !badtimespec, + cyg_timespec_to_ticks(abs_timeout)); + switch (err) { + + case Cyg_Mqueue::INTR: + errno = EINTR; + CYG_REPORT_RETVAL( -1 ); + return -1; + + case Cyg_Mqueue::WOULDBLOCK: + if (badtimespec) { + errno = EINVAL; + CYG_REPORT_RETVAL( -1 ); + return -1; + } + CYG_ASSERT( (user->flags & O_NONBLOCK) == O_NONBLOCK, + "Message queue assumed non-blocking when blocking requested" + ); + errno = EAGAIN; + CYG_REPORT_RETVAL( -1 ); + return -1; + + case Cyg_Mqueue::TIMEOUT: + errno = ETIMEDOUT; + CYG_REPORT_RETVAL( -1 ); + return -1; + + case Cyg_Mqueue::OK: + CYG_REPORT_RETVAL( 0 ); + return 0; + + default: + CYG_FAIL( "unhandled message queue return code" ); + return -1; // keep compiler happy + } // switch +} // mq_timedsend() + +//------------------------------------------------------------------------ + + +externC ssize_t +mq_timedreceive( mqd_t mqdes, char *msg_ptr, size_t msg_len, + unsigned int *msg_prio, const struct timespec *abs_timeout) +{ + CYG_REPORT_FUNCTYPE( "returning %ld" ); + CYG_REPORT_FUNCARG6( "mqdes=%08x, msg_ptr=%08x, msg_len=%u, msg_prio=%08x, + abs_timeout = %lu, %ld", + mqdes, msg_ptr, msg_len, msg_prio, + abs_timeout->tv_sec, abs_timeout->tv_nsec ); + CYG_CHECK_DATA_PTRC( msg_ptr ); + CYG_CHECK_DATA_PTRC( msg_ptr+msg_len-1 ); + if ( NULL != msg_prio ) + CYG_CHECK_DATA_PTRC( msg_prio ); + + + struct mquser *user = (struct mquser *)mqdes; + struct mqtabent *tabent = user->tabent; + +#ifdef CYGIMP_POSIX_MQUEUE_VALIDATE_DESCRIPTOR + if ( user->magic != MQ_VALID_MAGIC ) { + errno = EBADF; + CYG_REPORT_RETVAL( -1 ); + return (ssize_t)-1; + } +#endif + + if ( (O_RDONLY != (user->flags & O_RDONLY)) && + (O_RDWR != (user->flags & O_RDWR)) ) { + errno = EBADF; + CYG_REPORT_RETVAL( -1 ); + return (ssize_t)-1; + } + + if ( msg_len < (size_t)tabent->msgsize ) { + errno = EMSGSIZE; + CYG_REPORT_RETVAL( -1 ); + return (ssize_t)-1; + } + + // go for it + Cyg_Mqueue::qerr_t err; + bool nonblocking = ((user->flags & O_NONBLOCK) == O_NONBLOCK); + bool badtimespec = (abs_timeout->tv_nsec < 0) || + (abs_timeout->tv_nsec > 999999999l); + err = tabent->mq->get( msg_ptr, &msg_len, msg_prio, + !nonblocking && !badtimespec, + cyg_timespec_to_ticks(abs_timeout) ); + switch (err) { + + case Cyg_Mqueue::INTR: + errno = EINTR; + CYG_REPORT_RETVAL( -1 ); + return (ssize_t)-1; + + case Cyg_Mqueue::WOULDBLOCK: + if (badtimespec) { + errno = EINVAL; + CYG_REPORT_RETVAL( -1 ); + return -1; + } + CYG_ASSERT( (user->flags & O_NONBLOCK) == O_NONBLOCK, + "Message queue assumed non-blocking when blocking requested" + ); + errno = EAGAIN; + CYG_REPORT_RETVAL( -1 ); + return (ssize_t)-1; + + case Cyg_Mqueue::TIMEOUT: + errno = ETIMEDOUT; + CYG_REPORT_RETVAL( -1 ); + return -1; + + case Cyg_Mqueue::OK: + CYG_ASSERT( msg_len <= (size_t)tabent->msgsize, + "returned message too long" ); + if ( NULL != msg_prio ) + CYG_ASSERT( *msg_prio <= MQ_PRIO_MAX, + "returned message has invalid priority" ); + CYG_REPORT_RETVAL( msg_len ); + return (ssize_t)msg_len; + + default: + CYG_FAIL( "unhandled message queue return code" ); + return (ssize_t)-1; // keep compiler happy + } // switch + +} // mq_timedreceive() + +//------------------------------------------------------------------------ +#endif #ifdef CYGFUN_POSIX_MQUEUE_NOTIFY
