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 "build/build_config.h" 21 22 #if defined(OS_POSIX) 23 24 #include <errno.h> 25 26 #if defined(NDEBUG) 27 28 #define HANDLE_EINTR(x) ({ \ 29 decltype(x) eintr_wrapper_result; \ 30 do { \ 31 eintr_wrapper_result = (x); \ 32 } while (eintr_wrapper_result == -1 && errno == EINTR); \ 33 eintr_wrapper_result; \ 34 }) 35 36 #else 37 38 #define HANDLE_EINTR(x) ({ \ 39 int eintr_wrapper_counter = 0; \ 40 decltype(x) eintr_wrapper_result; \ 41 do { \ 42 eintr_wrapper_result = (x); \ 43 } while (eintr_wrapper_result == -1 && errno == EINTR && \ 44 eintr_wrapper_counter++ < 100); \ 45 eintr_wrapper_result; \ 46 }) 47 48 #endif // NDEBUG 49 50 #define IGNORE_EINTR(x) ({ \ 51 decltype(x) eintr_wrapper_result; \ 52 do { \ 53 eintr_wrapper_result = (x); \ 54 if (eintr_wrapper_result == -1 && errno == EINTR) { \ 55 eintr_wrapper_result = 0; \ 56 } \ 57 } while (0); \ 58 eintr_wrapper_result; \ 59 }) 60 61 #else // !OS_POSIX 62 63 #define HANDLE_EINTR(x) (x) 64 #define IGNORE_EINTR(x) (x) 65 66 #endif // !OS_POSIX 67 68 #endif // BASE_POSIX_EINTR_WRAPPER_H_ 69