Bug 1858509 add thread-safety annotations around MediaSourceDemuxer::mMonitor r=alwu
[gecko.git] / ipc / glue / FileDescriptorUtils.cpp
blobe4af78e79e36bf2f1d4285cf609a61b4262da4eb
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "FileDescriptorUtils.h"
9 #include "nsIEventTarget.h"
11 #include "nsCOMPtr.h"
12 #include "nsDebug.h"
13 #include "nsNetCID.h"
14 #include "nsServiceManagerUtils.h"
15 #include "prio.h"
16 #include "private/pprio.h"
18 #include <errno.h>
19 #ifdef XP_WIN
20 # include <io.h>
21 #else
22 # include <unistd.h>
23 #endif
25 using mozilla::ipc::CloseFileRunnable;
27 CloseFileRunnable::CloseFileRunnable(const FileDescriptor& aFileDescriptor)
28 : Runnable("CloseFileRunnable"), mFileDescriptor(aFileDescriptor) {
29 MOZ_ASSERT(aFileDescriptor.IsValid());
32 CloseFileRunnable::~CloseFileRunnable() {
33 if (mFileDescriptor.IsValid()) {
34 // It's probably safer to take the main thread IO hit here rather than leak
35 // the file descriptor.
36 CloseFile();
40 NS_IMPL_ISUPPORTS_INHERITED0(CloseFileRunnable, Runnable)
42 void CloseFileRunnable::Dispatch() {
43 nsCOMPtr<nsIEventTarget> eventTarget =
44 do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID);
45 NS_ENSURE_TRUE_VOID(eventTarget);
47 nsresult rv = eventTarget->Dispatch(this, NS_DISPATCH_NORMAL);
48 NS_ENSURE_SUCCESS_VOID(rv);
51 void CloseFileRunnable::CloseFile() {
52 // It's possible for this to happen on the main thread if the dispatch to the
53 // stream service fails so we can't assert the thread on which we're running.
54 mFileDescriptor = FileDescriptor();
57 NS_IMETHODIMP
58 CloseFileRunnable::Run() {
59 MOZ_ASSERT(!NS_IsMainThread());
61 CloseFile();
62 return NS_OK;
65 namespace mozilla {
66 namespace ipc {
68 FILE* FileDescriptorToFILE(const FileDescriptor& aDesc, const char* aOpenMode) {
69 if (!aDesc.IsValid()) {
70 errno = EBADF;
71 return nullptr;
73 auto handle = aDesc.ClonePlatformHandle();
74 #ifdef XP_WIN
75 int fd = _open_osfhandle(static_cast<intptr_t>(handle.get()), 0);
76 if (fd == -1) {
77 return nullptr;
79 Unused << handle.release();
80 #else
81 int fd = handle.release();
82 #endif
83 FILE* file = fdopen(fd, aOpenMode);
84 if (!file) {
85 int saved_errno = errno;
86 close(fd);
87 errno = saved_errno;
89 return file;
92 FileDescriptor FILEToFileDescriptor(FILE* aStream) {
93 if (!aStream) {
94 errno = EBADF;
95 return FileDescriptor();
97 #ifdef XP_WIN
98 int fd = _fileno(aStream);
99 if (fd == -1) {
100 return FileDescriptor();
102 return FileDescriptor(reinterpret_cast<HANDLE>(_get_osfhandle(fd)));
103 #else
104 return FileDescriptor(fileno(aStream));
105 #endif
108 } // namespace ipc
109 } // namespace mozilla