2b9b83b1ba
On POSIX systems, system calls can be interrupted by signals. In this case, they'll return EINTR, indicating that the system call needs to be restarted. (The situation is a little more complicated than this with SA_RESTART, but you can read man 7 signal if you like.) The short of it is that you need to catch EINTR and restart the call for these system calls: * read, readv, write, writev, ioctl * open() when dealing with a fifo * wait* * Anything socket based (send*, recv*, connect, accept etc) * flock and lock control with fcntl * mq_ functions which can block * futex * sem_wait (and timed wait) * pause, sigsuspend, sigtimedwait, sigwaitinfo * poll, epoll_wait, select and 'p' versions of the same * msgrcv, msgsnd, semop, semtimedop * close (although, on Linux, EINTR won't happen here) * any sleep functions (careful, you need to handle this are restart with different arguments) We've been a little sloppy with this until now. This patch adds a macro for dealing with this and corrects every case of these system calls (that I found). The macro is HANDLE_EINTR in base/eintr_wrapper.h. It's safe to include on Windows and is a no-op there. On POSIX, it uses GCC magic to return the correct type based on the expression and restarts the system call if it throws EINTR. And you can use it like: HANDLE_EINTR(close(fd)); Or: ssize_t bytes_read = HANDLE_EINTR(read(fd, buffer, len)); *BEWARE* that it will evaluate the argument multiple times, so this is not safe: HANDLE_EINTR(close(FireMissiles())); http://groups.google.com/group/chromium-dev/browse_thread/thread/41a35b2a457d73a0 http://codereview.chromium.org/100225 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@15102 0039d316-1c4b-4281-b951-d872f2087c98
34 linhas
750 B
C
34 linhas
750 B
C
// Copyright (c) 2009 The Chromium Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
// This provides a wrapper around system calls which may be interrupted by a
|
|
// signal and return EINTR. See man 7 signal.
|
|
//
|
|
// On Windows, this wrapper macro does nothing.
|
|
|
|
#ifndef BASE_EINTR_WRAPPER_H_
|
|
#define BASE_EINTR_WRAPPER_H_
|
|
|
|
#include "build/build_config.h"
|
|
|
|
#if defined(OS_POSIX)
|
|
|
|
#include <errno.h>
|
|
|
|
#define HANDLE_EINTR(x) ({ \
|
|
typeof(x) __eintr_result__; \
|
|
do { \
|
|
__eintr_result__ = x; \
|
|
} while (__eintr_result__ == -1 && errno == EINTR); \
|
|
__eintr_result__;\
|
|
})
|
|
|
|
#else
|
|
|
|
#define HANDLE_EINTR(x) x
|
|
|
|
#endif // OS_POSIX
|
|
|
|
#endif // !BASE_EINTR_WRAPPER_H_
|