1// Copyright 2014 The Android Open Source Project
2//
3// This software is licensed under the terms of the GNU General Public
4// License version 2, as published by the Free Software Foundation, and
5// may be copied, distributed, and modified under those terms.
6//
7// This program is distributed in the hope that it will be useful,
8// but WITHOUT ANY WARRANTY; without even the implied warranty of
9// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10// GNU General Public License for more details.
11#ifndef ANDROID_UTILS_EINTR_WRAPPER_H
12#define ANDROID_UTILS_EINTR_WRAPPER_H
13
14#include <errno.h>
15
16#include "android/utils/compiler.h"
17
18ANDROID_BEGIN_HEADER
19
20// Set EINTR_WRAPPER_DEBUG to 1 to force the debug version of HANDLE_EINTR
21// which will call android_eintr_wrapper_fatal() is the system call loops
22// too many times, or 0 to get it to loop indefinitly.
23// Mostly used for unit testing.
24// If the macro is undefined, auto-detect the value based on NDEBUG.
25#if !defined(EINTR_WRAPPER_DEBUG)
26#  ifdef NDEBUG
27#    define EINTER_WRAPPER_DEBUG 0
28#  else
29#    define EINTR_WRAPPER_DEBUG 1
30#  endif
31#endif
32
33// HANDLE_EINTR() is a macro used to handle EINTR return values when
34// calling system calls like open() or read() on Posix systems.
35//
36// By default, this will loop indefinitly, retrying the call until
37// the result is no longer -1/EINTR, except in debug mode, where a
38// loop counter is actually used and to provoke a fatal error if there
39// are too many loops.
40//
41// Usage example:
42//     int ret = HANDLE_EINTR(open("/some/file/path", O_RDONLY));
43//
44// IMPORTANT: Do not use with the close() system call (use IGNORE_EINTR()
45// instead).
46//
47// - On Linux, the file descriptor is always already closed when this
48//   function returns -1/EINTR, and calling it again with the same
49//   parameters risks closing another file descriptor open by another
50//   thread in parallel!
51//
52// - On OS X, whether the file descriptor is closed or not is pretty
53//   much random! It's better to leave the descriptor open than risk
54//   closing another one by mistake :(
55//
56#ifdef _WIN32
57#  define HANDLE_EINTR(x)  (x)
58#elif EINTR_WRAPPER_DEBUG == 0
59#  define HANDLE_EINTR(x) \
60    __extension__ ({ \
61        __typeof__(x) eintr_wrapper_result; \
62        do { \
63            eintr_wrapper_result = (x); \
64        } while (eintr_wrapper_result < 0 && errno == EINTR); \
65        eintr_wrapper_result; \
66    })
67#else  // !_WIN32 && EINTR_WRAPPER_DEBUG
68
69#  define MAX_EINTR_LOOP_COUNT  100
70
71#  define HANDLE_EINTR(x) \
72    __extension__ ({ \
73        __typeof__(x) eintr_wrapper_result; \
74        int eintr_wrapper_loop_count = 0; \
75        for (;;) { \
76            eintr_wrapper_result = (x); \
77            if (eintr_wrapper_result != -1 || errno != EINTR) \
78                break; \
79            if (++eintr_wrapper_loop_count >= MAX_EINTR_LOOP_COUNT) { \
80                android_eintr_wrapper_fatal( \
81                        __FILE__,__LINE__,__PRETTY_FUNCTION__,#x); \
82            } \
83        }; \
84        eintr_wrapper_result; \
85    })
86#endif  // !_WIN32 && EINTR_WRAPPER_DEBUG
87
88// IGNORE_EINTR() is a macro used to perform a system call and ignore
89// an EINTR result, i.e. it will return 0 instead of -1 if this occurs.
90// This is mostly used with the close() system call, as described
91// in the HANDLE_EINTR() documentation.
92#ifdef _WIN32
93#  define IGNORE_EINTR(x)  (x)
94#else
95#  define IGNORE_EINTR(x) \
96    __extension__ ({ \
97        __typeof__(x) eintr_wrapper_result = (x); \
98        if (eintr_wrapper_result == -1 && errno == EINTR) \
99            eintr_wrapper_result = 0; \
100        eintr_wrapper_result; \
101    })
102#endif
103
104#ifndef _WIN32
105// This function is called in debug mode only when a system call wrapped
106// by HANDLE_EINTR() failed more than MAX_EINTR_LOOP_COUNT times.
107// |file| is the source file location.
108// |lineno| is the line number in the source file.
109// |function| is the name of the function, or NULL if not available.
110// |call| is a string describing the system call that failed.
111void __attribute__((noreturn)) android_eintr_wrapper_fatal(
112        const char* file,
113        long lineno,
114        const char* function,
115        const char* call);
116#endif  // !_WIN32
117
118ANDROID_END_HEADER
119
120#endif  // ANDROID_UTILS_EINTR_WRAPPER_H
121