Index: dart/runtime/bin/eventhandler_linux.cc |
diff --git a/dart/runtime/bin/eventhandler_linux.cc b/dart/runtime/bin/eventhandler_linux.cc |
index 97b305b61e39d05aff432978f25ef07cf846879a..d7ba890f8c145356c87baadf49161f07b4f3f1f7 100644 |
--- a/dart/runtime/bin/eventhandler_linux.cc |
+++ b/dart/runtime/bin/eventhandler_linux.cc |
@@ -6,6 +6,7 @@ |
#if defined(TARGET_OS_LINUX) |
#include "bin/eventhandler.h" |
+#include "bin/eventhandler_linux.h" |
#include <errno.h> // NOLINT |
#include <pthread.h> // NOLINT |
@@ -20,6 +21,7 @@ |
#include "bin/dartutils.h" |
#include "bin/fdutils.h" |
#include "bin/log.h" |
+#include "bin/lockers.h" |
#include "bin/socket.h" |
#include "bin/thread.h" |
#include "platform/utils.h" |
@@ -210,12 +212,34 @@ void EventHandlerImplementation::HandleInterruptFd() { |
} else if (IS_COMMAND(msg[i].data, kCloseCommand)) { |
// Close the socket and free system resources and move on to next |
// message. |
- if (sd->RemovePort(msg[i].dart_port)) { |
+ bool no_more_listeners = sd->RemovePort(msg[i].dart_port); |
+ if (no_more_listeners) { |
RemoveFromEpollInstance(epoll_fd_, sd); |
+ } |
+ |
+ if (sd->IsListeningSocket()) { |
intptr_t fd = sd->fd(); |
- sd->Close(); |
- socket_map_.Remove(GetHashmapKeyFromFd(fd), GetHashmapHashFromFd(fd)); |
- delete sd; |
+ // We only close the socket file descriptor from the operating |
+ // system if there are no other dart socket objects which |
+ // are listening on the same (address, port) combination. |
+ { |
+ MutexLocker ml(globalTcpListeningSocketRegistry.mutex()); |
+ if (globalTcpListeningSocketRegistry.CloseSafe(sd->fd())) { |
+ ASSERT(no_more_listeners); |
+ socket_map_.Remove( |
+ GetHashmapKeyFromFd(fd), GetHashmapHashFromFd(fd)); |
+ sd->Close(); |
+ delete sd; |
+ } |
+ } |
+ } else { |
+ if (no_more_listeners) { |
+ intptr_t fd = sd->fd(); |
+ sd->Close(); |
Søren Gjesse
2015/01/29 09:05:51
Move sd->Close() down below the removal from the m
wibling
2015/01/29 09:42:01
Since it was closed before removal before shouldn'
Søren Gjesse
2015/01/29 10:12:55
As far as I can see this could be a potential bug
kustermann
2015/01/29 11:14:04
Yes, because only one thread owns/touches this, it
|
+ socket_map_.Remove( |
+ GetHashmapKeyFromFd(fd), GetHashmapHashFromFd(fd)); |
+ delete sd; |
+ } |
} |
DartUtils::PostInt32(msg[i].dart_port, 1 << kDestroyedEvent); |
} else if (IS_COMMAND(msg[i].data, kReturnTokenCommand)) { |