From 7db9e218e477c4dc19042f95391a9712cc1bc4d2 Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Wed, 23 Jul 2008 21:39:38 +0000 Subject: [PATCH] julun+mauricek: * rc uses a global instance of BResources. On destruction it calls Unset() of the BFile member fFile. BNode::Unset then calls close_fd(), which parses the static global DescriptorMap to actually close the descriptor. However on Cygwin the DescriptorMap has been destroyed already for some reason, thus accessing it is invalid. The "fix" is to put the map on the heap and delete it as soon as it gets empty. This way the global BResources instance can be freed without a crash. * If someone likes to review, feel free to, it didn't cause any issues here git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@26585 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/build/libroot/fs_descriptors.cpp | 39 +++++++++++++++++----------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/src/build/libroot/fs_descriptors.cpp b/src/build/libroot/fs_descriptors.cpp index f871b18aaf..4e4fb118c2 100644 --- a/src/build/libroot/fs_descriptors.cpp +++ b/src/build/libroot/fs_descriptors.cpp @@ -23,7 +23,7 @@ using std::map; static const int kVirtualDescriptorStart = 10000; typedef map DescriptorMap; -static DescriptorMap sDescriptors; +static DescriptorMap *sDescriptors = 0; namespace BPrivate { @@ -91,7 +91,7 @@ FileDescriptor::Close() return errno; } - return B_OK; + return B_OK; } // Dup @@ -101,7 +101,7 @@ FileDescriptor::Dup(Descriptor *&clone) int dupFD = dup(fd); if (dupFD < 0) return errno; - + clone = new FileDescriptor(dupFD); return B_OK; } @@ -150,7 +150,7 @@ DirectoryDescriptor::Close() return errno; } - return B_OK; + return B_OK; } // Dup @@ -165,7 +165,7 @@ DirectoryDescriptor::Dup(Descriptor *&clone) DIR *dupDir = opendir(path.c_str()); if (!dupDir) return errno; - + clone = new DirectoryDescriptor(dupDir, ref); return B_OK; } @@ -213,7 +213,7 @@ SymlinkDescriptor::SymlinkDescriptor(const char *path) status_t SymlinkDescriptor::Close() { - return B_OK; + return B_OK; } // Dup @@ -276,7 +276,7 @@ AttrDirDescriptor::Close() return errno; } - return B_OK; + return B_OK; } // Dup @@ -309,8 +309,10 @@ AttrDirDescriptor::GetNodeRef(NodeRef &ref) Descriptor * get_descriptor(int fd) { - DescriptorMap::iterator it = sDescriptors.find(fd); - if (it == sDescriptors.end()) + if (!sDescriptors) + return NULL; + DescriptorMap::iterator it = sDescriptors->find(fd); + if (it == sDescriptors->end()) return NULL; return it->second; } @@ -319,18 +321,21 @@ get_descriptor(int fd) int add_descriptor(Descriptor *descriptor) { + if (!sDescriptors) + sDescriptors = new DescriptorMap; + int fd = -1; if (FileDescriptor *file = dynamic_cast(descriptor)) { fd = file->fd; } else { // find a free slot for (fd = kVirtualDescriptorStart; - sDescriptors.find(fd) != sDescriptors.end(); + sDescriptors->find(fd) != sDescriptors->end(); fd++) { } } - sDescriptors[fd] = descriptor; + (*sDescriptors)[fd] = descriptor; descriptor->fd = fd; return fd; @@ -340,14 +345,18 @@ add_descriptor(Descriptor *descriptor) status_t delete_descriptor(int fd) { - DescriptorMap::iterator it = sDescriptors.find(fd); - if (it == sDescriptors.end()) + DescriptorMap::iterator it = sDescriptors->find(fd); + if (it == sDescriptors->end()) return B_FILE_ERROR; status_t error = it->second->Close(); delete it->second; - sDescriptors.erase(it); - + sDescriptors->erase(it); + + if (sDescriptors->size() == 0) { + delete sDescriptors; + sDescriptors = 0; + } return error; }