The POLLHUP seems to happen quite frequently (revents=17), so I will filter the log messages in that case.
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, ¤t_time); >> + osaf_timespec_subtract(¤t_time, &start_time, >> + &elapsed_time); >> + if (osaf_timespec_compare(¤t_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, ¤t_time); >> + osaf_timespec_subtract(¤t_time, &start_time, >> + &elapsed_time); >> + if (osaf_timespec_compare(¤t_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