1 // Copyright 2012 The Chromium Authors 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 does nothing because there are no 12 // signals. 13 // 14 // Don't wrap close calls in WrapEINTR. Use IGNORE_EINTR macro if the return 15 // value of close is significant. See http://crbug.com/269623. 16 17 #ifndef PARTITION_ALLOC_PARTITION_ALLOC_BASE_POSIX_EINTR_WRAPPER_H_ 18 #define PARTITION_ALLOC_PARTITION_ALLOC_BASE_POSIX_EINTR_WRAPPER_H_ 19 20 #include "build/build_config.h" 21 22 #if BUILDFLAG(IS_POSIX) 23 #include <cerrno> 24 #include <utility> 25 #endif 26 27 namespace partition_alloc { 28 #if BUILDFLAG(IS_POSIX) 29 30 template <typename Fn> WrapEINTR(Fn fn)31inline auto WrapEINTR(Fn fn) { 32 return [fn](auto&&... args) { 33 int out = -1; 34 #if defined(NDEBUG) 35 while (true) 36 #else 37 for (int retry_count = 0; retry_count < 100; ++retry_count) 38 #endif 39 { 40 out = fn(std::forward<decltype(args)>(args)...); 41 if (out != -1 || errno != EINTR) { 42 return out; 43 } 44 } 45 return out; 46 }; 47 } 48 49 #else // !BUILDFLAG(IS_POSIX) 50 51 template <typename Fn> 52 inline auto WrapEINTR(Fn fn) { 53 return fn; 54 } 55 56 #endif // !BUILDFLAG(IS_POSIX) 57 58 } // namespace partition_alloc 59 60 #endif // PARTITION_ALLOC_PARTITION_ALLOC_BASE_POSIX_EINTR_WRAPPER_H_ 61