Changeset 203155 in webkit
- Timestamp:
- Jul 13, 2016 1:36:01 AM (8 years ago)
- Location:
- trunk/Source
- Files:
-
- 9 edited
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WTF/ChangeLog
r203147 r203155 1 2016-07-13 Carlos Garcia Campos <cgarcia@igalia.com> 2 3 [GTK] WebKitGtk+ uses too many file descriptors 4 https://bugs.webkit.org/show_bug.cgi?id=152316 5 6 Reviewed by Michael Catanzaro. 7 8 Add helper functions to duplicate a file descriptor setting close on exec flag, and also to set close on exec 9 flag to an existing file descriptor. 10 11 * wtf/UniStdExtras.h: 12 * wtf/UniStdExtras.cpp 13 (WTF::setCloseOnExec): 14 (WTF::dupCloseOnExec): 15 1 16 2016-07-12 Benjamin Poulain <bpoulain@apple.com> 2 17 -
trunk/Source/WTF/wtf/PlatformEfl.cmake
r203038 r203155 1 1 list(APPEND WTF_SOURCES 2 2 PlatformUserPreferredLanguagesUnix.cpp 3 UniStdExtras.cpp 3 4 4 5 text/efl/TextBreakIteratorInternalICUEfl.cpp -
trunk/Source/WTF/wtf/PlatformGTK.cmake
r203038 r203155 9 9 glib/RunLoopGLib.cpp 10 10 PlatformUserPreferredLanguagesUnix.cpp 11 UniStdExtras.cpp 11 12 12 13 text/gtk/TextBreakIteratorInternalICUGtk.cpp -
trunk/Source/WTF/wtf/UniStdExtras.cpp
r203154 r203155 1 1 /* 2 * Copyright (C) 201 3 Nokia Corporation and/or its subsidiary(-ies).2 * Copyright (C) 2016 Igalia S.L. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 24 24 */ 25 25 26 #i fndef UniStdExtras_h27 # define UniStdExtras_h26 #include "config.h" 27 #include "UniStdExtras.h" 28 28 29 #include <errno.h> 30 #include <unistd.h> 29 #include <fcntl.h> 31 30 32 31 namespace WTF { 33 32 34 inline int closeWithRetry(int fileDescriptor)33 bool setCloseOnExec(int fileDescriptor) 35 34 { 36 int ret; 37 #if OS(LINUX) 38 // Workaround for the Linux behavior of closing the descriptor 39 // unconditionally, even if the close() call is interrupted. 40 // See https://bugs.webkit.org/show_bug.cgi?id=117266 for more 41 // details. 42 if ((ret = close(fileDescriptor)) == -1 && errno == EINTR) 43 return 0; 44 #else 45 while ((ret = close(fileDescriptor)) == -1 && errno == EINTR) { } 35 int returnValue = -1; 36 do { 37 int flags = fcntl(fileDescriptor, F_GETFD); 38 if (flags != -1) 39 returnValue = fcntl(fileDescriptor, F_SETFD, flags | FD_CLOEXEC); 40 } while (returnValue == -1 && errno == EINTR); 41 42 return returnValue != -1; 43 } 44 45 int dupCloseOnExec(int fileDescriptor) 46 { 47 int duplicatedFileDescriptor = -1; 48 #ifdef F_DUPFD_CLOEXEC 49 while ((duplicatedFileDescriptor = fcntl(fileDescriptor, F_DUPFD_CLOEXEC, 0)) == -1 && errno == EINTR) { } 50 if (duplicatedFileDescriptor != -1) 51 return duplicatedFileDescriptor; 52 46 53 #endif 47 return ret; 54 55 while ((duplicatedFileDescriptor = dup(fileDescriptor)) == -1 && errno == EINTR) { } 56 if (duplicatedFileDescriptor == -1) 57 return -1; 58 59 if (!setCloseOnExec(duplicatedFileDescriptor)) { 60 closeWithRetry(duplicatedFileDescriptor); 61 return -1; 62 } 63 64 return duplicatedFileDescriptor; 48 65 } 49 66 50 67 } // namespace WTF 51 52 using WTF::closeWithRetry;53 54 #endif // UniStdExtras_h -
trunk/Source/WTF/wtf/UniStdExtras.h
r151825 r203155 32 32 namespace WTF { 33 33 34 bool setCloseOnExec(int fileDescriptor); 35 int dupCloseOnExec(int fileDescriptor); 36 34 37 inline int closeWithRetry(int fileDescriptor) 35 38 { … … 51 54 52 55 using WTF::closeWithRetry; 56 using WTF::setCloseOnExec; 57 using WTF::dupCloseOnExec; 53 58 54 59 #endif // UniStdExtras_h -
trunk/Source/WebKit2/ChangeLog
r203145 r203155 1 2016-07-13 Carlos Garcia Campos <cgarcia@igalia.com> 2 3 [GTK] WebKitGtk+ uses too many file descriptors 4 https://bugs.webkit.org/show_bug.cgi?id=152316 5 6 Reviewed by Michael Catanzaro. 7 8 The problem is that we are keeping file descriptors open in SharedMemory objects. Those objects can be kept 9 alive for a long time, for example in case of cached resources sent from the network process as shareable 10 resources. The thing is that we keep the file descriptor in the SharedMemory object only to be able to create a 11 Handle, duplicating the file descriptor. However, we are also assuming that we create handles for SharedMemory 12 objects created by another handle which is wrong. SharedMemory objects are created to map a file or data and 13 then a handle is created to send it to another process, or to map an existing file or data for a given handle 14 received from another process. They can also be created to wrap another map, but in that case we don't own the 15 file descritor nor the mapped data. So, after mapping from a handle, we no longer need the file descriptor, and 16 it can be closed to release it, while the mapped memory data will still be alive until munmap() is called. This 17 drastically reduces the amount of file descriptors used by WebKitGTK+. 18 19 * Platform/IPC/unix/ConnectionUnix.cpp: 20 (IPC::readBytesFromSocket): Use setCloseOnExec(). 21 (IPC::Connection::createPlatformConnection): Ditto. 22 * Platform/SharedMemory.h: 23 * Platform/unix/SharedMemoryUnix.cpp: 24 (WebKit::SharedMemory::map): Close the file descriptor right after mmap. 25 (WebKit::SharedMemory::~SharedMemory): Close the file descriptor only if it hasn't been closed yet. 26 (WebKit::SharedMemory::createHandle): Add an ASSERT to ensure we only try to create a handle for SharedMemory 27 objects having a valid file descriptor. Use dupCloseOnExec() to duplicate the handle and set the close on exec flag. 28 * UIProcess/Launcher/gtk/ProcessLauncherGtk.cpp: 29 (WebKit::ProcessLauncher::launchProcess): Use setCloseOnExec(). 30 1 31 2016-07-12 Simon Fraser <simon.fraser@apple.com> 2 32 -
trunk/Source/WebKit2/Platform/IPC/unix/ConnectionUnix.cpp
r201381 r203155 309 309 310 310 for (size_t i = 0; i < fileDescriptorsCount; ++i) { 311 while (fcntl(fileDescriptors[previousFileDescriptorsSize + i], F_SETFD, FD_CLOEXEC) == -1) { 312 if (errno != EINTR) { 313 ASSERT_NOT_REACHED(); 314 break; 315 } 311 if (!setCloseOnExec(fileDescriptors[previousFileDescriptorsSize + i])) { 312 ASSERT_NOT_REACHED(); 313 break; 316 314 } 317 315 } … … 533 531 if (options & SetCloexecOnServer) { 534 532 // Don't expose the child socket to the parent process. 535 while (fcntl(sockets[1], F_SETFD, FD_CLOEXEC) == -1)536 RELEASE_ASSERT (errno != EINTR);533 if (!setCloseOnExec(sockets[1])) 534 RELEASE_ASSERT_NOT_REACHED(); 537 535 } 538 536 539 537 if (options & SetCloexecOnClient) { 540 538 // Don't expose the parent socket to potential future children. 541 while (fcntl(sockets[0], F_SETFD, FD_CLOEXEC) == -1)542 RELEASE_ASSERT (errno != EINTR);539 if (!setCloseOnExec(sockets[0])) 540 RELEASE_ASSERT_NOT_REACHED(); 543 541 } 544 542 -
trunk/Source/WebKit2/Platform/SharedMemory.h
r191856 r203155 114 114 115 115 #if USE(UNIX_DOMAIN_SOCKETS) 116 intm_fileDescriptor;116 Optional<int> m_fileDescriptor; 117 117 bool m_isWrappingMap { false }; 118 118 #elif OS(DARWIN) -
trunk/Source/WebKit2/Platform/unix/SharedMemoryUnix.cpp
r194496 r203155 153 153 ASSERT(!handle.isNull()); 154 154 155 void* data = mmap(0, handle.m_attachment.size(), accessModeMMap(protection), MAP_SHARED, handle.m_attachment.fileDescriptor(), 0); 155 int fd = handle.m_attachment.releaseFileDescriptor(); 156 void* data = mmap(0, handle.m_attachment.size(), accessModeMMap(protection), MAP_SHARED, fd, 0); 157 closeWithRetry(fd); 156 158 if (data == MAP_FAILED) 157 159 return nullptr; 158 160 159 RefPtr<SharedMemory> instance = wrapMap(data, handle.m_attachment.size(), handle.m_attachment.releaseFileDescriptor()); 161 RefPtr<SharedMemory> instance = wrapMap(data, handle.m_attachment.size(), -1); 162 instance->m_fileDescriptor = Nullopt; 160 163 instance->m_isWrappingMap = false; 161 164 return instance; … … 174 177 SharedMemory::~SharedMemory() 175 178 { 176 if (!m_isWrappingMap) { 177 munmap(m_data, m_size); 178 closeWithRetry(m_fileDescriptor); 179 } 179 if (m_isWrappingMap) 180 return; 181 182 munmap(m_data, m_size); 183 if (m_fileDescriptor) 184 closeWithRetry(m_fileDescriptor.value()); 180 185 } 181 186 … … 183 188 { 184 189 ASSERT_ARG(handle, handle.isNull()); 190 ASSERT(m_fileDescriptor); 185 191 186 192 // FIXME: Handle the case where the passed Protection is ReadOnly. 187 193 // See https://bugs.webkit.org/show_bug.cgi?id=131542. 188 194 189 int duplicatedHandle; 190 while ((duplicatedHandle = dup(m_fileDescriptor)) == -1) { 191 if (errno != EINTR) { 192 ASSERT_NOT_REACHED(); 193 return false; 194 } 195 } 196 197 while (fcntl(duplicatedHandle, F_SETFD, FD_CLOEXEC) == -1) { 198 if (errno != EINTR) { 199 ASSERT_NOT_REACHED(); 200 closeWithRetry(duplicatedHandle); 201 return false; 202 } 195 int duplicatedHandle = dupCloseOnExec(m_fileDescriptor.value()); 196 if (duplicatedHandle == -1) { 197 ASSERT_NOT_REACHED(); 198 return false; 203 199 } 204 200 handle.m_attachment = IPC::Attachment(duplicatedHandle, m_size); -
trunk/Source/WebKit2/UIProcess/Launcher/gtk/ProcessLauncherGtk.cpp
r196548 r203155 39 39 #include <locale.h> 40 40 #include <wtf/RunLoop.h> 41 #include <wtf/UniStdExtras.h> 41 42 #include <wtf/glib/GLibUtilities.h> 42 43 #include <wtf/glib/GUniquePtr.h> … … 126 127 127 128 // Don't expose the parent socket to potential future children. 128 while (fcntl(socketPair.client, F_SETFD, FD_CLOEXEC) == -1)129 RELEASE_ASSERT (errno != EINTR);129 if (!setCloseOnExec(socketPair.client)) 130 RELEASE_ASSERT_NOT_REACHED(); 130 131 131 132 close(socketPair.client);
Note: See TracChangeset
for help on using the changeset viewer.