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
This commit is contained in:
Maurice Kalinowski
2008-07-23 21:39:38 +00:00
parent 59c40b2f95
commit 7db9e218e4
+24 -15
View File
@@ -23,7 +23,7 @@ using std::map;
static const int kVirtualDescriptorStart = 10000; static const int kVirtualDescriptorStart = 10000;
typedef map<int, BPrivate::Descriptor*> DescriptorMap; typedef map<int, BPrivate::Descriptor*> DescriptorMap;
static DescriptorMap sDescriptors; static DescriptorMap *sDescriptors = 0;
namespace BPrivate { namespace BPrivate {
@@ -91,7 +91,7 @@ FileDescriptor::Close()
return errno; return errno;
} }
return B_OK; return B_OK;
} }
// Dup // Dup
@@ -101,7 +101,7 @@ FileDescriptor::Dup(Descriptor *&clone)
int dupFD = dup(fd); int dupFD = dup(fd);
if (dupFD < 0) if (dupFD < 0)
return errno; return errno;
clone = new FileDescriptor(dupFD); clone = new FileDescriptor(dupFD);
return B_OK; return B_OK;
} }
@@ -150,7 +150,7 @@ DirectoryDescriptor::Close()
return errno; return errno;
} }
return B_OK; return B_OK;
} }
// Dup // Dup
@@ -165,7 +165,7 @@ DirectoryDescriptor::Dup(Descriptor *&clone)
DIR *dupDir = opendir(path.c_str()); DIR *dupDir = opendir(path.c_str());
if (!dupDir) if (!dupDir)
return errno; return errno;
clone = new DirectoryDescriptor(dupDir, ref); clone = new DirectoryDescriptor(dupDir, ref);
return B_OK; return B_OK;
} }
@@ -213,7 +213,7 @@ SymlinkDescriptor::SymlinkDescriptor(const char *path)
status_t status_t
SymlinkDescriptor::Close() SymlinkDescriptor::Close()
{ {
return B_OK; return B_OK;
} }
// Dup // Dup
@@ -276,7 +276,7 @@ AttrDirDescriptor::Close()
return errno; return errno;
} }
return B_OK; return B_OK;
} }
// Dup // Dup
@@ -309,8 +309,10 @@ AttrDirDescriptor::GetNodeRef(NodeRef &ref)
Descriptor * Descriptor *
get_descriptor(int fd) get_descriptor(int fd)
{ {
DescriptorMap::iterator it = sDescriptors.find(fd); if (!sDescriptors)
if (it == sDescriptors.end()) return NULL;
DescriptorMap::iterator it = sDescriptors->find(fd);
if (it == sDescriptors->end())
return NULL; return NULL;
return it->second; return it->second;
} }
@@ -319,18 +321,21 @@ get_descriptor(int fd)
int int
add_descriptor(Descriptor *descriptor) add_descriptor(Descriptor *descriptor)
{ {
if (!sDescriptors)
sDescriptors = new DescriptorMap;
int fd = -1; int fd = -1;
if (FileDescriptor *file = dynamic_cast<FileDescriptor*>(descriptor)) { if (FileDescriptor *file = dynamic_cast<FileDescriptor*>(descriptor)) {
fd = file->fd; fd = file->fd;
} else { } else {
// find a free slot // find a free slot
for (fd = kVirtualDescriptorStart; for (fd = kVirtualDescriptorStart;
sDescriptors.find(fd) != sDescriptors.end(); sDescriptors->find(fd) != sDescriptors->end();
fd++) { fd++) {
} }
} }
sDescriptors[fd] = descriptor; (*sDescriptors)[fd] = descriptor;
descriptor->fd = fd; descriptor->fd = fd;
return fd; return fd;
@@ -340,14 +345,18 @@ add_descriptor(Descriptor *descriptor)
status_t status_t
delete_descriptor(int fd) delete_descriptor(int fd)
{ {
DescriptorMap::iterator it = sDescriptors.find(fd); DescriptorMap::iterator it = sDescriptors->find(fd);
if (it == sDescriptors.end()) if (it == sDescriptors->end())
return B_FILE_ERROR; return B_FILE_ERROR;
status_t error = it->second->Close(); status_t error = it->second->Close();
delete it->second; delete it->second;
sDescriptors.erase(it); sDescriptors->erase(it);
if (sDescriptors->size() == 0) {
delete sDescriptors;
sDescriptors = 0;
}
return error; return error;
} }