1 // Copyright 2013 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 #include "mojo/edk/embedder/platform_handle.h"
6
7 #include "build/build_config.h"
8 #if defined(OS_POSIX)
9 #include <unistd.h>
10 #elif defined(OS_WIN)
11 #include <windows.h>
12 #else
13 #error "Platform not yet supported."
14 #endif
15
16 #include "base/logging.h"
17
18 namespace mojo {
19 namespace edk {
20
CloseIfNecessary()21 void PlatformHandle::CloseIfNecessary() {
22 if (!is_valid())
23 return;
24
25 #if defined(OS_POSIX)
26 if (type == Type::POSIX) {
27 bool success = (close(handle) == 0);
28 DPCHECK(success);
29 handle = -1;
30 }
31 #if defined(OS_MACOSX) && !defined(OS_IOS)
32 else if (type == Type::MACH) {
33 kern_return_t rv = mach_port_deallocate(mach_task_self(), port);
34 DPCHECK(rv == KERN_SUCCESS);
35 port = MACH_PORT_NULL;
36 }
37 #endif // defined(OS_MACOSX) && !defined(OS_IOS)
38 #elif defined(OS_WIN)
39 if (owning_process != base::GetCurrentProcessHandle()) {
40 // This handle may have been duplicated to a new target process but not yet
41 // sent there. In this case CloseHandle should NOT be called. From MSDN
42 // documentation for DuplicateHandle[1]:
43 //
44 // Normally the target process closes a duplicated handle when that
45 // process is finished using the handle. To close a duplicated handle
46 // from the source process, call DuplicateHandle with the following
47 // parameters:
48 //
49 // * Set hSourceProcessHandle to the target process from the
50 // call that created the handle.
51 // * Set hSourceHandle to the duplicated handle to close.
52 // * Set lpTargetHandle to NULL.
53 // * Set dwOptions to DUPLICATE_CLOSE_SOURCE.
54 //
55 // [1] https://msdn.microsoft.com/en-us/library/windows/desktop/ms724251
56 //
57 // NOTE: It's possible for this operation to fail if the owning process
58 // was terminated or is in the process of being terminated. Either way,
59 // there is nothing we can reasonably do about failure, so we ignore it.
60 DuplicateHandle(owning_process, handle, NULL, &handle, 0, FALSE,
61 DUPLICATE_CLOSE_SOURCE);
62 return;
63 }
64
65 bool success = !!CloseHandle(handle);
66 DPCHECK(success);
67 handle = INVALID_HANDLE_VALUE;
68 #else
69 #error "Platform not yet supported."
70 #endif
71 }
72
73 } // namespace edk
74 } // namespace mojo
75