Ok, I will add error loggings and push this later today.

regards,
Anders Widell

2013-11-29 09:53, Mathivanan Naickan Palanivelu skrev:
> Ack.
> Good that you were able to work on this ticket, would be a good value add.
> One comment is that, we should log the fd and strerror(errno) in the cases
> when poll returned 1.
> In the absence of this information, it would be a big cycle of time loss 
> going back to the field
> to collect debug information.
>
> So basically, after the below condition
> +       result = osaf_poll(&set, 1, i_timeout);
> +       if (result == 1) {
>
> Just print fd, revents, strerror(errno)
>
> Cheers,
> Mathi.
>
>> -----Original Message-----
>> From: Anders Widell [mailto:anders.wid...@ericsson.com]
>> Sent: Tuesday, October 08, 2013 3:51 PM
>> To: Ramesh Babu Betham
>> Cc: opensaf-devel@lists.sourceforge.net
>> Subject: [devel] [PATCH 1 of 1] base: Add osaf_poll.h and osaf_time.h APIs
>> [#580]
>>
>>   osaf/libs/core/common/Makefile.am         |    2 +
>>   osaf/libs/core/common/include/osaf_poll.h |   97 +++++++
>>   osaf/libs/core/common/include/osaf_time.h |  371
>> ++++++++++++++++++++++++++++++
>>   osaf/libs/core/common/osaf_poll.c         |  130 ++++++++++
>>   osaf/libs/core/common/osaf_time.c         |   52 ++++
>>   5 files changed, 652 insertions(+), 0 deletions(-)
>>
>>
>> Add new utility and convenience APIs, declared in osaf_poll.h and
>> osaf_time.h, respectively.
>>
>> osaf_poll.h contains utility functions that work in a similar way as the 
>> Linux
>> function poll() and ppoll(), except that they handle errors themselves 
>> instead
>> of returning -1. The errno value EINTR is handled with a loop, and the
>> functions keep track of time so that the time-out will happen at the same
>> time no matter if the functions were interrupted by a signal or not. Other
>> errno values will cause the process to be aborted, since they indicate the
>> presence of a software bug and the program cannot continue in a safe way.
>>
>> osaf_time.h contains utility functions for reading the time and sleeping, 
>> that
>> work in a similar way as the Linux functions clock_gettime() and nanosleep(),
>> except that they abort the process instead of returning -1. There are also
>> utilty functions for manipulating "struct timespec" times. struct timespec is
>> used for representing a time in many POSIX functions, and the reason for
>> having a structure is that a 64-bit integer is not sufficient for 
>> representing the
>> full time.
>>
>> diff --git a/osaf/libs/core/common/Makefile.am
>> b/osaf/libs/core/common/Makefile.am
>> --- a/osaf/libs/core/common/Makefile.am
>> +++ b/osaf/libs/core/common/Makefile.am
>> @@ -32,6 +32,8 @@ libopensaf_common_la_SOURCES = \
>>      ncs_sprr.c \
>>      logtrace.c \
>>      osaf_utility.c \
>> +    osaf_poll.c \
>> +    osaf_time.c \
>>      nid_start_util.c \
>>      saf_edu.c \
>>      daemon.c \
>> diff --git a/osaf/libs/core/common/include/osaf_poll.h
>> b/osaf/libs/core/common/include/osaf_poll.h
>> new file mode 100644
>> --- /dev/null
>> +++ b/osaf/libs/core/common/include/osaf_poll.h
>> @@ -0,0 +1,97 @@
>> +/*      -*- OpenSAF  -*-
>> + *
>> + * (C) Copyright 2013 The OpenSAF Foundation
>> + *
>> + * This program is distributed in the hope that it will be useful, but
>> + * WITHOUT ANY WARRANTY; without even the implied warranty of
>> +MERCHANTABILITY
>> + * or FITNESS FOR A PARTICULAR PURPOSE. This file and program are
>> +licensed
>> + * under the GNU Lesser General Public License Version 2.1, February 1999.
>> + * The complete license can be accessed from the following location:
>> + * http://opensource.org/licenses/lgpl-license.php
>> + * See the Copying file included with the OpenSAF distribution for full
>> + * licensing terms.
>> + *
>> + * Author(s): Ericsson AB
>> + *
>> + */
>> +
>> +/** @file
>> + *
>> + * This file contains an OpenSAF replacement of the POSIX function
>> +poll(). The
>> + * definitions in this file are for internal use within OpenSAF only.
>> + */
>> +
>> +#ifndef OPENSAF_BASE_OSAF_POLL_H_
>> +#define OPENSAF_BASE_OSAF_POLL_H_
>> +
>> +#include <poll.h>
>> +#include <time.h>
>> +#include <signal.h>
>> +
>> +#ifdef      __cplusplus
>> +extern "C" {
>> +#endif
>> +
>> +/**
>> + * @brief Wait for events on file descriptors
>> + *
>> + * This is a convenience function that behaves exactly like the POSIX
>> +function
>> + * poll(3P), except that it will abort the process instead of returning
>> +an error
>> + * code in case of a failure. It handles the EINTR case internally with
>> +a loop,
>> + * and ensures that the function will time out at the same time no
>> +matter if the
>> + * system call was interrupted by a signal or not.
>> + *
>> + * The return value will always be in the range [0, i_nfds].
>> + */
>> +extern unsigned osaf_poll(struct pollfd* io_fds, nfds_t i_nfds, int
>> +i_timeout);
>> +
>> +/**
>> + * @brief Wait for events on file descriptors
>> + *
>> + * This is a convenience function that behaves exactly like the Linux
>> +function
>> + * ppoll(3), except that it will abort the process instead of returning
>> +an error
>> + * code in case of a failure. It handles the EINTR case internally with
>> +a loop,
>> + * and ensures that the function will time out at the same time no
>> +matter if the
>> + * system call was interrupted by a signal or not. Note that since the
>> +ppoll()
>> + * function is currently not included in LSB, this function is
>> +implemented
>> + * internally using poll(). Therefore, the @a i_sigmask parameter is
>> +not
>> + * supported and must be set to NULL.
>> + *
>> + * The return value will always be in the range [0, i_nfds].
>> + */
>> +extern unsigned osaf_ppoll(struct pollfd* io_fds, nfds_t i_nfds,
>> +    const struct timespec* i_timeout_ts, const sigset_t* i_sigmask);
>> +
>> +/**
>> + * @brief Wait for events on a file descriptor
>> + *
>> + * This is a convenience function that behaves exactly like the POSIX
>> +function
>> + * poll(3P), except that it only supports waiting for read events on
>> +one single
>> + * file descriptor passed as the parameter @a i_fd. Also, it will abort
>> +the
>> + * process instead of returning an error code in case the poll()
>> +function
>> + * fails. It handles the EINTR case internally with a loop, and ensures
>> +that the
>> + * function will time out at the same time no matter if the system call
>> +was
>> + * interrupted by a signal or not.
>> + *
>> + * Since there is no struct pollfd* parameter, this convenience
>> +function has a
>> + * different way of reporting what events were received on the file
>> +descriptor
>> + * @a i_fd. It will return 1 if there was a POLLIN event on the file
>> +descriptor
>> + * (just like poll() does). But if poll() returned an error event for
>> +the file
>> + * descriptor @a i_fd, this function will handle the there different
>> +cases as
>> + * follows:
>> + *
>> + * POLLNVAL - in this case the process will be aborted.
>> + *
>> + * POLLERR - errno will be set to EIO and -1 will be returned.
>> + *
>> + * POLLHUP - errno will be set to EPIPE and -1 will be returned.
>> + *
>> + * The return value from this function will always be in the range [-1, 1].
>> + */
>> +extern int osaf_poll_one_fd(int i_fd, int i_timeout);
>> +
>> +#ifdef      __cplusplus
>> +}
>> +#endif
>> +
>> +#endif      /* OPENSAF_BASE_OSAF_POLL_H_ */
>> diff --git a/osaf/libs/core/common/include/osaf_time.h
>> b/osaf/libs/core/common/include/osaf_time.h
>> new file mode 100644
>> --- /dev/null
>> +++ b/osaf/libs/core/common/include/osaf_time.h
>> @@ -0,0 +1,371 @@
>> +/*      -*- OpenSAF  -*-
>> + *
>> + * (C) Copyright 2013 The OpenSAF Foundation
>> + *
>> + * This program is distributed in the hope that it will be useful, but
>> + * WITHOUT ANY WARRANTY; without even the implied warranty of
>> +MERCHANTABILITY
>> + * or FITNESS FOR A PARTICULAR PURPOSE. This file and program are
>> +licensed
>> + * under the GNU Lesser General Public License Version 2.1, February 1999.
>> + * The complete license can be accessed from the following location:
>> + * http://opensource.org/licenses/lgpl-license.php
>> + * See the Copying file included with the OpenSAF distribution for full
>> + * licensing terms.
>> + *
>> + * Author(s): Ericsson AB
>> + *
>> + */
>> +
>> +/** @file
>> + *
>> + * This file contains utility functions related to time and time conversion.
>> + * Many functions operate on timespec structures, and require that the
>> +structure
>> + * is normalized. By this is meant that the tv_nsec member of the
>> +structure has
>> + * a value in the range [0, 999999999]. The osaf_normalize_timespec()
>> +function
>> + * can be used to convert a timespec strucure to normalized form, when
>> + * necessary. Negative times are not supported.
>> + *
>> + * The definitions in this file are for internal use within OpenSAF
>> +only. For
>> + * performace reasons, which may be important e.g. when doing time
>> +measurements,
>> + * all functions are declared as inline.
>> + */
>> +
>> +#ifndef OPENSAF_BASE_OSAF_TIME_H_
>> +#define OPENSAF_BASE_OSAF_TIME_H_
>> +
>> +#include <stdint.h>
>> +#include <time.h>
>> +#include <sys/time.h>
>> +#include "osaf_utility.h"
>> +
>> +#ifdef      __cplusplus
>> +extern "C" {
>> +#endif
>> +
>> +enum {
>> +    /**
>> +     *  Number of nanoseconds per second.
>> +     */
>> +    kNanosPerSec = 1000000000,
>> +    /**
>> +     *  Number of milliseconds per second.
>> +     */
>> +    kMicrosPerSec = 1000000,
>> +    /**
>> +     *  Number of microseconds per second.
>> +     */
>> +    kMillisPerSec = 1000
>> +};
>> +
>> +/**
>> + * @brief Sleep for the specified time
>> + *
>> + * This is a convenience function that behaves exactly like the POSIX
>> +function
>> + * nanosleep(3P), except that it will abort the process instead of
>> +returning an
>> + * error code in case of a failure. In case the thread was interrupted
>> +by a
>> + * signal, nanosleep() will be called again to sleep the remaining time.
>> + */
>> +extern void osaf_nanosleep(const struct timespec* i_req);
>> +
>> +/**
>> + * @brief Get the time
>> + *
>> + * This is a convenience function that behaves exactly like the POSIX
>> +function
>> + * clock_gettime(3P), except that it will abort the process instead of
>> +returning
>> + * an error code in case of a failure.
>> + */
>> +static inline void osaf_clock_gettime(clockid_t i_clk_id,
>> +    struct timespec* o_ts);
>> +
>> +/**
>> + * @brief Normalize a timespec structure.
>> + *
>> + * This function normalizes the timespec structure @a i_ts and stores
>> +the result
>> + * in the output parameter @a o_nrm. The tv_nsec member of the
>> +normalized
>> + * structure is guaranteed to be in the range [0, 999999999]. The
>> +parameters are
>> + * allowed to point to the same memory address.
>> + */
>> +static inline void osaf_normalize_timespec(const struct timespec* i_ts,
>> +    struct timespec* o_nrm);
>> +
>> +/**
>> + * @brief Calculate the sum of two timespec structures.
>> + *
>> + * This function adds the two timespec structures @a i_time1 and @a
>> +i_time2, and
>> + * stores the result in the output parameter @a o_sum. The input
>> +parameters @a
>> + * i_time1 and @a i_time2 must be normalized, and the output parameter
>> +@a o_sum
>> + * is guaranteed to also be normalized. The parameters are allowed to
>> +point to
>> + * the same memory address. Negative times are not supported.
>> + */
>> +static inline void osaf_timespec_add(const struct timespec* i_time1,
>> +    const struct timespec* i_time2,
>> +    struct timespec* o_sum);
>> +
>> +/**
>> + * @brief Calculate the difference between two timespec structures.
>> + *
>> + * This function subtracts the timespec structure @a i_start from the
>> +timespec
>> + * structure @a i_end, and stores the result in the output parameter @a
>> + * o_difference. The input parameters @a i_end and @a i_start must be
>> + * normalized, and the output parameter @a o_difference is guaranteed
>> +to also be
>> + * normalized. The parameters are allowed to point to the same memory
>> + * address. Negative times are not supported.
>> + */
>> +static inline void osaf_timespec_subtract(const struct timespec* i_end,
>> +    const struct timespec* i_start,
>> +    struct timespec* o_difference);
>> +
>> +/**
>> + * @brief Compare two timespec structures.
>> + *
>> + * This function compares the two timespec structures @a i_end and @a
>> i_start.
>> + * The return value will be -1, 0 or 1, if @a i_end is less than, equal
>> +to, or
>> + * greater than @a i_start, respectively. The input parameters @a i_end
>> +and @a
>> + * i_start must be normalized.
>> + */
>> +static inline int osaf_timespec_compare(const struct timespec* i_end,
>> +    const struct timespec* i_start);
>> +
>> +/**
>> + * @brief Convert a timespec structure to a timeval structure.
>> + *
>> + * This function converts the timespec structure @a i_ts to a timeval
>> +structure,
>> + * and stores the result in the output parameter @a o_tv. The input
>> +parameter @a
>> + * i_ts does not have to be normalized. The output parameter @a o_tv
>> +will be
>> + * normalized if the input parameter @a i_ts was normalized. The
>> +parameters are
>> + * allowed to point to the same memory address.
>> + */
>> +static inline void osaf_timespec_to_timeval(const struct timespec* i_ts,
>> +    struct timeval* o_tv);
>> +
>> +/**
>> + * @brief Convert a timeval structure to a timespec structure.
>> + *
>> + * This function converts the timeval structure @a i_tv to a timespec
>> +structure,
>> + * and stores the result in the output parameter @a o_ts. The input
>> +parameter @a
>> + * i_tv does not have to be normalized. The output parameter @a o_ts
>> +will be
>> + * normalized if the input parameter @a i_tv was normalized. The
>> +parameters are
>> + * allowed to point to the same memory address.
>> + */
>> +static inline void osaf_timeval_to_timespec(const struct timeval* i_tv,
>> +    struct timespec* o_ts);
>> +
>> +/**
>> + * @brief Convert an integer representing time in milliseconds to a
>> +timespec
>> + * structure.
>> + *
>> + * This function converts the integer @a i_millis to a timespec
>> +structure, and
>> + * stores the result in the output parameter @a o_ts. The unit of @a
>> +i_millis is
>> + * milliseconds. The output parameter @a o_ts is guaranteed to be
>> normalized.
>> + */
>> +static inline void osaf_millis_to_timespec(uint64_t i_millis,
>> +    struct timespec* o_ts);
>> +
>> +/**
>> + * @brief Convert an integer representing time in microseconds to a
>> +timespec
>> + * structure.
>> + *
>> + * This function converts the integer @a i_micros to a timespec
>> +structure, and
>> + * stores the result in the output parameter @a o_ts. The unit of @a
>> +i_micros is
>> + * microseconds. The output parameter @a o_ts is guaranteed to be
>> normalized.
>> + */
>> +static inline void osaf_micros_to_timespec(uint64_t i_micros,
>> +    struct timespec* o_ts);
>> +
>> +/**
>> + * @brief Convert a double representing time in seconds to a timespec
>> structure.
>> + *
>> + * This function converts the double precision floating point number @a
>> + * i_seconds to a timespec structure, and stores the result in the
>> +output
>> + * parameter @a o_ts. The unit of @a i_seconds is microseconds. The
>> +output
>> + * parameter @a o_ts is guaranteed to be normalized.
>> + */
>> +static inline void osaf_double_to_timespec(double i_seconds,
>> +    struct timespec* o_ts);
>> +
>> +/**
>> + * @brief Convert an integer representing time in nanoseconds to a
>> +timespec
>> + * structure.
>> + *
>> + * This function converts the integer @a i_nanos to a timespec
>> +structure, and
>> + * stores the result in the output parameter @a o_ts. The unit of @a
>> +i_nanos is
>> + * nanoseconds. The output parameter @a o_ts is guaranteed to be
>> normalized.
>> + */
>> +static inline void osaf_nanos_to_timespec(uint64_t i_nanos,
>> +    struct timespec* o_ts);
>> +
>> +/**
>> + * @brief Convert a timespec structure to an integer representing time
>> + * in milliseconds.
>> + *
>> + * This function converts the timespec structure @a i_ts to an integer
>> + * representing time in milliseconds. The result will be rounded down.
>> +Note that
>> + * the returned unsigned 64-bit integer has a smaller range than the
>> +range than
>> + * what is possible to represent in a timespec structure.
>> + */
>> +static inline uint64_t osaf_timespec_to_millis(const struct timespec*
>> +i_ts);
>> +
>> +/**
>> + * @brief Convert a timespec structure to an integer representing time
>> + * in microseconds.
>> + *
>> + * This function converts the timespec structure @a i_ts to an integer
>> + * representing time in microseconds. The result will be rounded down.
>> +Note that
>> + * the returned unsigned 64-bit integer has a smaller range than the
>> +range than
>> + * what is possible to represent in a timespec structure.
>> + */
>> +static inline uint64_t osaf_timespec_to_micros(const struct timespec*
>> +i_ts);
>> +
>> +/**
>> + * @brief Convert a timespec structure to an integer representing time
>> + * in nanoseconds.
>> + *
>> + * This function converts the timespec structure @a i_ts to an integer
>> + * representing time in nanoseconds. Note that the returned unsigned
>> +64-bit
>> + * integer has a smaller range than the range than what is possible to
>> +represent
>> + * in a timespec structure.
>> + */
>> +static inline uint64_t osaf_timespec_to_nanos(const struct timespec*
>> +i_ts);
>> +
>> +/**
>> + * @brief Convert a timespec structure to a double representing time in
>> + * seconds.
>> + *
>> + * This function converts the timespec structure @a i_ts to a double
>> +precision
>> + * floating point number. The input parameter @a i_ts does not have to
>> +be
>> + * normalized. The unit of the returned value is seconds. Note you will
>> +lose
>> + * precision when converting to a double.
>> + */
>> +static inline double osaf_timespec_to_double(const struct timespec*
>> +i_ts);
>> +
>> +static inline void osaf_clock_gettime(clockid_t i_clk_id, struct
>> +timespec* o_ts) {
>> +    if (clock_gettime(i_clk_id, o_ts) != 0) osaf_abort(i_clk_id); }
>> +
>> +static inline void osaf_normalize_timespec(const struct timespec* i_ts,
>> +    struct timespec* o_nrm)
>> +{
>> +    time_t sec = i_ts->tv_sec + i_ts->tv_nsec / kNanosPerSec;
>> +    long nsec = i_ts->tv_nsec % kNanosPerSec;
>> +    if (nsec < 0) {
>> +            sec -= 1;
>> +            nsec += kNanosPerSec;
>> +    }
>> +    o_nrm->tv_sec = sec;
>> +    o_nrm->tv_nsec = nsec;
>> +}
>> +
>> +static inline void osaf_timespec_add(const struct timespec* i_time1,
>> +    const struct timespec* i_time2,
>> +    struct timespec* o_sum)
>> +{
>> +    time_t sec = i_time1->tv_sec + i_time2->tv_sec;
>> +    long nsec = i_time1->tv_nsec + i_time2->tv_nsec;
>> +    if (nsec >= kNanosPerSec) {
>> +            sec += 1;
>> +            nsec -= kNanosPerSec;
>> +    }
>> +    o_sum->tv_sec = sec;
>> +    o_sum->tv_nsec = nsec;
>> +}
>> +
>> +static inline void osaf_timespec_subtract(const struct timespec* i_end,
>> +    const struct timespec* i_start,
>> +    struct timespec* o_difference)
>> +{
>> +    time_t sec = i_end->tv_sec - i_start->tv_sec;
>> +    long nsec = i_end->tv_nsec - i_start->tv_nsec;
>> +    if (nsec < 0) {
>> +            sec -= 1;
>> +            nsec += kNanosPerSec;
>> +    }
>> +    o_difference->tv_sec = sec;
>> +    o_difference->tv_nsec = nsec;
>> +}
>> +
>> +static inline int osaf_timespec_compare(const struct timespec* i_end,
>> +    const struct timespec* i_start)
>> +{
>> +    if (i_end->tv_sec == i_start->tv_sec) {
>> +            if (i_end->tv_nsec < i_start->tv_nsec) return -1;
>> +            return i_end->tv_nsec != i_start->tv_nsec ? 1 : 0;
>> +    }
>> +    return i_end->tv_sec > i_start->tv_sec ? 1 : -1; }
>> +
>> +static inline void osaf_timespec_to_timeval(const struct timespec* i_ts,
>> +    struct timeval* o_tv)
>> +{
>> +    time_t sec = i_ts->tv_sec;
>> +    suseconds_t usec = i_ts->tv_nsec / (kMicrosPerSec / kMillisPerSec);
>> +    o_tv->tv_sec = sec;
>> +    o_tv->tv_usec = usec;
>> +}
>> +
>> +static inline void osaf_timeval_to_timespec(const struct timeval* i_tv,
>> +    struct timespec* o_ts)
>> +{
>> +    time_t sec = i_tv->tv_sec;
>> +    long nsec = ((long) i_tv->tv_usec) * (kMicrosPerSec / kMillisPerSec);
>> +    o_ts->tv_sec = sec;
>> +    o_ts->tv_nsec = nsec;
>> +}
>> +
>> +static inline void osaf_millis_to_timespec(uint64_t i_millis,
>> +    struct timespec* o_ts)
>> +{
>> +    o_ts->tv_sec = i_millis / kMillisPerSec;
>> +    o_ts->tv_nsec = (i_millis % kMillisPerSec) * (kNanosPerSec /
>> +            kMillisPerSec);
>> +}
>> +
>> +static inline void osaf_micros_to_timespec(uint64_t i_micros,
>> +    struct timespec* o_ts)
>> +{
>> +    o_ts->tv_sec = i_micros / kMicrosPerSec;
>> +    o_ts->tv_nsec = (i_micros % kMicrosPerSec) * (kNanosPerSec /
>> +            kMicrosPerSec);
>> +}
>> +
>> +static inline void osaf_nanos_to_timespec(uint64_t i_nanos,
>> +    struct timespec* o_ts)
>> +{
>> +    o_ts->tv_sec = i_nanos / kNanosPerSec;
>> +    o_ts->tv_nsec = i_nanos % kNanosPerSec; }
>> +
>> +static inline void osaf_double_to_timespec(double i_seconds,
>> +    struct timespec* o_ts)
>> +{
>> +    o_ts->tv_sec = i_seconds;
>> +    o_ts->tv_nsec = (i_seconds - o_ts->tv_sec) * kNanosPerSec;
>> +    osaf_normalize_timespec(o_ts, o_ts);
>> +}
>> +
>> +static inline uint64_t osaf_timespec_to_millis(const struct timespec*
>> +i_ts) {
>> +    return i_ts->tv_sec * (uint64_t) kMillisPerSec + i_ts->tv_nsec /
>> +            (kNanosPerSec / kMillisPerSec);
>> +}
>> +
>> +static inline uint64_t osaf_timespec_to_micros(const struct timespec*
>> +i_ts) {
>> +    return i_ts->tv_sec * (uint64_t) kMicrosPerSec + i_ts->tv_nsec /
>> +            (kNanosPerSec / kMicrosPerSec);
>> +}
>> +
>> +static inline uint64_t osaf_timespec_to_nanos(const struct timespec*
>> +i_ts) {
>> +    return i_ts->tv_sec * (uint64_t) kNanosPerSec + i_ts->tv_nsec; }
>> +
>> +static inline double osaf_timespec_to_double(const struct timespec*
>> +i_ts) {
>> +    return i_ts->tv_sec + i_ts->tv_nsec / (double) kNanosPerSec; }
>> +
>> +#ifdef      __cplusplus
>> +}
>> +#endif
>> +
>> +#endif      /* OPENSAF_BASE_OSAF_TIME_H_ */
>> diff --git a/osaf/libs/core/common/osaf_poll.c
>> b/osaf/libs/core/common/osaf_poll.c
>> new file mode 100644
>> --- /dev/null
>> +++ b/osaf/libs/core/common/osaf_poll.c
>> @@ -0,0 +1,130 @@
>> +/*      -*- OpenSAF  -*-
>> + *
>> + * (C) Copyright 2013 The OpenSAF Foundation
>> + *
>> + * This program is distributed in the hope that it will be useful, but
>> + * WITHOUT ANY WARRANTY; without even the implied warranty of
>> +MERCHANTABILITY
>> + * or FITNESS FOR A PARTICULAR PURPOSE. This file and program are
>> +licensed
>> + * under the GNU Lesser General Public License Version 2.1, February 1999.
>> + * The complete license can be accessed from the following location:
>> + * http://opensource.org/licenses/lgpl-license.php
>> + * See the Copying file included with the OpenSAF distribution for full
>> + * licensing terms.
>> + *
>> + * Author(s): Ericsson AB
>> + *
>> + */
>> +
>> +#include "osaf_poll.h"
>> +#include <errno.h>
>> +#include <limits.h>
>> +#include "osaf_time.h"
>> +#include "osaf_utility.h"
>> +
>> +static unsigned osaf_poll_no_timeout(struct pollfd* io_fds, nfds_t
>> +i_nfds);
>> +
>> +static unsigned osaf_poll_no_timeout(struct pollfd* io_fds, nfds_t
>> +i_nfds) {
>> +    int result;
>> +    for (;;) {
>> +            result = poll(io_fds, i_nfds, -1);
>> +            if (result >= 0) break;
>> +            if (result < 0 && errno != EINTR) osaf_abort(result);
>> +    }
>> +    return result;
>> +}
>> +
>> +unsigned osaf_poll(struct pollfd* io_fds, nfds_t i_nfds, int i_timeout)
>> +{
>> +    struct timespec timeout_ts;
>> +    if (i_timeout < 0) return osaf_poll_no_timeout(io_fds, i_nfds);
>> +    osaf_millis_to_timespec(i_timeout, &timeout_ts);
>> +    return osaf_ppoll(io_fds, i_nfds, &timeout_ts, NULL); }
>> +
>> +unsigned osaf_ppoll(struct pollfd* io_fds, nfds_t i_nfds,
>> +    const struct timespec* i_timeout_ts, const sigset_t* i_sigmask) {
>> +    static const struct timespec millisecond_round_up = {
>> +            0, (kNanosPerSec / kMillisPerSec) - 1
>> +    };
>> +    static const struct timespec max_possible_timeout = {
>> +            INT_MAX / kMillisPerSec,
>> +            (INT_MAX % kMillisPerSec) * (kNanosPerSec / kMillisPerSec)
>> +    };
>> +    struct timespec start_time;
>> +    struct timespec time_left_ts;
>> +    int result;
>> +
>> +    if (i_sigmask != NULL) osaf_abort(EINVAL);
>> +    if (i_timeout_ts == NULL) return osaf_poll_no_timeout(io_fds,
>> i_nfds);
>> +
>> +    osaf_clock_gettime(CLOCK_MONOTONIC, &start_time);
>> +    time_left_ts = *i_timeout_ts;
>> +
>> +    for (;;) {
>> +            struct timespec current_time;
>> +            struct timespec elapsed_time;
>> +            int time_left;
>> +
>> +            /* We don't want to time-out too early, so round up to next
>> even
>> +             * number of milliseconds.
>> +             */
>> +            osaf_timespec_add(&time_left_ts, &millisecond_round_up,
>> +                    &time_left_ts);
>> +
>> +            if (osaf_timespec_compare(&time_left_ts,
>> +                    &max_possible_timeout) < 0) {
>> +                    time_left = osaf_timespec_to_millis(&time_left_ts);
>> +            } else {
>> +                    time_left = INT_MAX;
>> +            }
>> +
>> +            /* ppoll() is currently not included in LSB, so we have to use
>> +             * poll() here unfortunately.
>> +             */
>> +            result = poll(io_fds, i_nfds, time_left);
>> +            if (result > 0 || (result == 0 && time_left < INT_MAX)) break;
>> +            if (result < 0 && errno != EINTR) osaf_abort(result);
>> +
>> +            osaf_clock_gettime(CLOCK_MONOTONIC, &current_time);
>> +            osaf_timespec_subtract(&current_time, &start_time,
>> +                    &elapsed_time);
>> +            if (osaf_timespec_compare(&current_time, &start_time) <
>> 0) {
>> +                    /* Handle the unlikely case that the elapsed time is
>> +                     * negative. Shouldn't happen with a monotonic
>> clock,
>> +                     * but just to be on the safe side.
>> +                     */
>> +                    elapsed_time.tv_sec = 0;
>> +                    elapsed_time.tv_nsec = 0;
>> +            }
>> +            if (osaf_timespec_compare(&elapsed_time, i_timeout_ts)
>>> = 0) {
>> +                    result = 0;
>> +                    break;
>> +            }
>> +            osaf_timespec_subtract(i_timeout_ts, &elapsed_time,
>> +                    &time_left_ts);
>> +    }
>> +    return result;
>> +}
>> +
>> +int osaf_poll_one_fd(int i_fd, int i_timeout) {
>> +    struct pollfd set;
>> +    unsigned result;
>> +    set.fd = i_fd;
>> +    set.events = POLLIN;
>> +    result = osaf_poll(&set, 1, i_timeout);
>> +    if (result == 1) {
>> +            if ((set.revents & POLLNVAL) != 0) osaf_abort(set.revents);
>> +            if ((set.revents & POLLERR) != 0) {
>> +                    errno = EIO;
>> +                    return -1;
>> +            }
>> +            if ((set.revents & POLLHUP) != 0) {
>> +                    errno = EPIPE;
>> +                    return -1;
>> +            }
>> +    }
>> +    return result;
>> +}
>> diff --git a/osaf/libs/core/common/osaf_time.c
>> b/osaf/libs/core/common/osaf_time.c
>> new file mode 100644
>> --- /dev/null
>> +++ b/osaf/libs/core/common/osaf_time.c
>> @@ -0,0 +1,52 @@
>> +/*      -*- OpenSAF  -*-
>> + *
>> + * (C) Copyright 2013 The OpenSAF Foundation
>> + *
>> + * This program is distributed in the hope that it will be useful, but
>> + * WITHOUT ANY WARRANTY; without even the implied warranty of
>> +MERCHANTABILITY
>> + * or FITNESS FOR A PARTICULAR PURPOSE. This file and program are
>> +licensed
>> + * under the GNU Lesser General Public License Version 2.1, February 1999.
>> + * The complete license can be accessed from the following location:
>> + * http://opensource.org/licenses/lgpl-license.php
>> + * See the Copying file included with the OpenSAF distribution for full
>> + * licensing terms.
>> + *
>> + * Author(s): Ericsson AB
>> + *
>> + */
>> +
>> +#include "osaf_time.h"
>> +#include <errno.h>
>> +
>> +void osaf_nanosleep(const struct timespec* i_req) {
>> +    struct timespec req = *i_req;
>> +    struct timespec start_time;
>> +    osaf_clock_gettime(CLOCK_MONOTONIC, &start_time);
>> +    for (;;) {
>> +            struct timespec current_time;
>> +            struct timespec elapsed_time;
>> +            /* We could have utilised the second parameter to
>> nanosleep(),
>> +             * which will return the remaining sleep time in the case
>> +             * nanosleep() was interrupted by a signal. But this gives
>> +             * inaccurate sleep time, for various reasons. See the man
>> page
>> +             * of nanosleep(2) for details.
>> +             */
>> +            int result = nanosleep(&req, NULL);
>> +            if (result == 0) break;
>> +            if (errno != EINTR) osaf_abort(result);
>> +            osaf_clock_gettime(CLOCK_MONOTONIC, &current_time);
>> +            osaf_timespec_subtract(&current_time, &start_time,
>> +                    &elapsed_time);
>> +            if (osaf_timespec_compare(&current_time, &start_time) <
>> 0) {
>> +                    /* Handle the unlikely case that the elapsed time is
>> +                     * negative. Shouldn't happen with a monotonic
>> clock,
>> +                     * but just to be on the safe side.
>> +                     */
>> +                    elapsed_time.tv_sec = 0;
>> +                    elapsed_time.tv_nsec = 0;
>> +            }
>> +            if (osaf_timespec_compare(&elapsed_time, i_req) >= 0)
>> break;
>> +            osaf_timespec_subtract(i_req, &elapsed_time, &req);
>> +    }
>> +}
>>
>> ------------------------------------------------------------------------------
>> October Webinars: Code for Performance
>> Free Intel webinars can help you accelerate application performance.
>> Explore tips for MPI, OpenMP, advanced profiling, and more. Get the most
>> from the latest Intel processors and coprocessors. See abstracts and register
>> http://pubads.g.doubleclick.net/gampad/clk?id=60134071&iu=/4140/ostg.clk
>> trk
>> _______________________________________________
>> Opensaf-devel mailing list
>> Opensaf-devel@lists.sourceforge.net
>> https://lists.sourceforge.net/lists/listinfo/opensaf-devel


------------------------------------------------------------------------------
Rapidly troubleshoot problems before they affect your business. Most IT 
organizations don't have a clear picture of how application performance 
affects their revenue. With AppDynamics, you get 100% visibility into your 
Java,.NET, & PHP application. Start your 15-day FREE TRIAL of AppDynamics Pro!
http://pubads.g.doubleclick.net/gampad/clk?id=84349351&iu=/4140/ostg.clktrk
_______________________________________________
Opensaf-devel mailing list
Opensaf-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/opensaf-devel

Reply via email to