From ff443c9f5e0631e263b0e3515d5140f10dbbe8ca Mon Sep 17 00:00:00 2001 From: Jonas 'Sortie' Termansen Date: Thu, 9 Jan 2014 00:57:41 +0100 Subject: [PATCH] Thread-secure dregister(3) and dunregister(3). --- libc/dirent/dcloseall.cpp | 2 ++ libc/dirent/dregister.cpp | 3 +++ libc/dirent/dunregister.cpp | 5 +++++ 3 files changed, 10 insertions(+) diff --git a/libc/dirent/dcloseall.cpp b/libc/dirent/dcloseall.cpp index 84ef862e..0afeeeae 100644 --- a/libc/dirent/dcloseall.cpp +++ b/libc/dirent/dcloseall.cpp @@ -31,6 +31,8 @@ extern "C" { DIR* __firstdir = NULL; } extern "C" int dcloseall(void) { int result = 0; + // We do not lock __firstdir_lock here because this function is called on + // process termination and only one thread can call exit(3). while ( __firstdir ) result |= closedir(__firstdir); return result ? EOF : 0; diff --git a/libc/dirent/dregister.cpp b/libc/dirent/dregister.cpp index 6e05106e..2026fd9c 100644 --- a/libc/dirent/dregister.cpp +++ b/libc/dirent/dregister.cpp @@ -24,6 +24,9 @@ #include #include +#include + +extern "C" pthread_mutex_t __dirname_lock; extern "C" void dregister(DIR* dir) { diff --git a/libc/dirent/dunregister.cpp b/libc/dirent/dunregister.cpp index 2b1d544f..6a3a7e22 100644 --- a/libc/dirent/dunregister.cpp +++ b/libc/dirent/dunregister.cpp @@ -24,11 +24,15 @@ #include #include +#include + +extern "C" { pthread_mutex_t __dirname_lock = PTHREAD_MUTEX_INITIALIZER; } extern "C" void dunregister(DIR* dir) { if ( !(dir->flags & _DIR_REGISTERED) ) return; + pthread_mutex_lock(&__dirname_lock); if ( !dir->prev ) __firstdir = dir->next; if ( dir->prev ) @@ -36,4 +40,5 @@ extern "C" void dunregister(DIR* dir) if ( dir->next ) dir->next->prev = dir->prev; dir->flags &= ~_DIR_REGISTERED; + pthread_mutex_unlock(&__dirname_lock); }