Index: chrome/common/ipc_message_utils.h |
diff --git a/chrome/common/ipc_message_utils.h b/chrome/common/ipc_message_utils.h |
index e877221f1150f2e1a0e1eef63ef206ce7932f696..4fd917bec0bd7e3c6569c98a576ab68e3b36e4d3 100644 |
--- a/chrome/common/ipc_message_utils.h |
+++ b/chrome/common/ipc_message_utils.h |
@@ -16,7 +16,6 @@ |
#if defined(OS_POSIX) |
#include "chrome/common/file_descriptor_set_posix.h" |
#endif |
-#include "chrome/common/ipc_maybe.h" |
#include "chrome/common/ipc_sync_message.h" |
#include "chrome/common/thumbnail_score.h" |
#include "chrome/common/transport_dib.h" |
@@ -694,15 +693,45 @@ struct ParamTraits<gfx::Size> { |
}; |
#if defined(OS_POSIX) |
+// FileDescriptors may be serialised over IPC channels on POSIX. On the |
+// receiving side, the FileDescriptor is a valid duplicate of the file |
+// descriptor which was transmitted: *it is not just a copy of the integer like |
+// HANDLEs on Windows*. The only exception is if the file descriptor is < 0. In |
+// this case, the receiving end will see a value of -1. *Zero is a valid file |
+// descriptor*. |
+// |
+// The received file descriptor will have the |auto_close| flag set to true. The |
+// code which handles the message is responsible for taking ownership of it. |
+// File descriptors are OS resources and must be closed when no longer needed. |
+// |
+// When sending a file descriptor, the file descriptor must be valid at the time |
+// of transmission. Since transmission is not synchronous, one should consider |
+// dup()ing any file descriptors to be transmitted and setting the |auto_close| |
+// flag, which causes the file descriptor to be closed after writing. |
template<> |
struct ParamTraits<base::FileDescriptor> { |
typedef base::FileDescriptor param_type; |
static void Write(Message* m, const param_type& p) { |
- if (!m->WriteFileDescriptor(p)) |
- NOTREACHED(); |
+ const bool valid = p.fd >= 0; |
+ WriteParam(m, valid); |
+ |
+ if (valid) { |
+ if (!m->WriteFileDescriptor(p)) |
+ NOTREACHED(); |
+ } |
} |
static bool Read(const Message* m, void** iter, param_type* r) { |
- return m->ReadFileDescriptor(iter, r); |
+ bool valid; |
+ if (!ReadParam(m, iter, &valid)) |
+ return false; |
+ |
+ if (valid) { |
+ return m->ReadFileDescriptor(iter, r); |
+ } else { |
darin (slow to review)
2009/03/05 19:42:12
nit: no need for else after return
|
+ r->fd = -1; |
+ r->auto_close = false; |
+ return true; |
+ } |
} |
static void Log(const param_type& p, std::wstring* l) { |
if (p.auto_close) { |
@@ -947,34 +976,6 @@ struct ParamTraits<TransportDIB::Id> { |
}; |
#endif |
-template<typename A> |
-struct ParamTraits<Maybe<A> > { |
- typedef struct Maybe<A> param_type; |
- static void Write(Message* m, const param_type& p) { |
- WriteParam(m, p.valid); |
- if (p.valid) |
- WriteParam(m, p.value); |
- } |
- static bool Read(const Message* m, void** iter, param_type* r) { |
- if (!ReadParam(m, iter, &r->valid)) |
- return false; |
- |
- if (r->valid) |
- return ReadParam(m, iter, &r->value); |
- return true; |
- } |
- static void Log(const param_type& p, std::wstring* l) { |
- if (p.valid) { |
- l->append(L"Just "); |
- ParamTraits<A>::Log(p.value, l); |
- } else { |
- l->append(L"Nothing"); |
- } |
- |
- } |
-}; |
- |
- |
template <> |
struct ParamTraits<Message> { |
static void Write(Message* m, const Message& p) { |
@@ -996,7 +997,6 @@ struct ParamTraits<Message> { |
} |
}; |
- |
template <> |
struct ParamTraits<Tuple0> { |
typedef Tuple0 param_type; |