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