• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 // This provides a wrapper around system calls which may be interrupted by a
6 // signal and return EINTR. See man 7 signal.
7 // To prevent long-lasting loops (which would likely be a bug, such as a signal
8 // that should be masked) to go unnoticed, there is a limit after which the
9 // caller will nonetheless see an EINTR in Debug builds.
10 //
11 // On Windows and Fuchsia, this wrapper macro does nothing because there are no
12 // signals.
13 //
14 // Don't wrap close calls in HANDLE_EINTR. Use IGNORE_EINTR if the return
15 // value of close is significant. See http://crbug.com/269623.
16 
17 #ifndef BASE_POSIX_EINTR_WRAPPER_H_
18 #define BASE_POSIX_EINTR_WRAPPER_H_
19 
20 #include "util/build_config.h"
21 
22 #if defined(OS_POSIX) && !defined(OS_FUCHSIA)
23 
24 #include <errno.h>
25 
26 #if defined(NDEBUG)
27 
28 #define HANDLE_EINTR(x)                                     \
29   ({                                                        \
30     decltype(x) eintr_wrapper_result;                       \
31     do {                                                    \
32       eintr_wrapper_result = (x);                           \
33     } while (eintr_wrapper_result == -1 && errno == EINTR); \
34     eintr_wrapper_result;                                   \
35   })
36 
37 #else
38 
39 #define HANDLE_EINTR(x)                                      \
40   ({                                                         \
41     int eintr_wrapper_counter = 0;                           \
42     decltype(x) eintr_wrapper_result;                        \
43     do {                                                     \
44       eintr_wrapper_result = (x);                            \
45     } while (eintr_wrapper_result == -1 && errno == EINTR && \
46              eintr_wrapper_counter++ < 100);                 \
47     eintr_wrapper_result;                                    \
48   })
49 
50 #endif  // NDEBUG
51 
52 #define IGNORE_EINTR(x)                                   \
53   ({                                                      \
54     decltype(x) eintr_wrapper_result;                     \
55     do {                                                  \
56       eintr_wrapper_result = (x);                         \
57       if (eintr_wrapper_result == -1 && errno == EINTR) { \
58         eintr_wrapper_result = 0;                         \
59       }                                                   \
60     } while (0);                                          \
61     eintr_wrapper_result;                                 \
62   })
63 
64 #else  // !OS_POSIX || OS_FUCHSIA
65 
66 #define HANDLE_EINTR(x) (x)
67 #define IGNORE_EINTR(x) (x)
68 
69 #endif  // !OS_POSIX || OS_FUCHSIA
70 
71 #endif  // BASE_POSIX_EINTR_WRAPPER_H_
72