From f0e34ffc8319dfa6ac271d79f3293f72b772ba52 Mon Sep 17 00:00:00 2001 From: paulbeach Date: Wed, 19 Dec 2007 14:35:52 +0000 Subject: [PATCH] Apply MacOS changes to HEAD --- extern/icu/source/common/putil.c | 7 +++ src/common/classes/semaphore.cpp | 84 ++++++++++++++++++++++++++++++++ src/common/classes/semaphore.h | 23 +++++++++ src/jrd/divorce.cpp | 25 +++++++--- src/remote/inet_server.cpp | 10 ++-- 5 files changed, 139 insertions(+), 10 deletions(-) create mode 100644 src/common/classes/semaphore.cpp diff --git a/extern/icu/source/common/putil.c b/extern/icu/source/common/putil.c index 81bb5e40b9..cf288ac33f 100644 --- a/extern/icu/source/common/putil.c +++ b/extern/icu/source/common/putil.c @@ -48,6 +48,13 @@ #define _XOPEN_SOURCE 4 #endif +#if defined(DARWIN) +/* Have to undef this because we cannot build a +backwards compatible version of ICU for Tiger (MacOS 10.4) +on Leopard (MacOS 10.5). Due to UNIX2003 support included +in MacOS 10.5 */ +#undef _XOPEN_SOURCE +#endif /* Define __USE_POSIX and __USE_XOPEN for Linux and glibc. */ #ifndef __USE_POSIX #define __USE_POSIX diff --git a/src/common/classes/semaphore.cpp b/src/common/classes/semaphore.cpp new file mode 100644 index 0000000000..935ff86d4b --- /dev/null +++ b/src/common/classes/semaphore.cpp @@ -0,0 +1,84 @@ +/* + * PROGRAM: Client/Server Common Code + * MODULE: locks.cpp + * DESCRIPTION: Darwin specific semaphore support + * + * The contents of this file are subject to the Initial + * Developer's Public License Version 1.0 (the "License"); + * you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * http://www.ibphoenix.com/main.nfs?a=ibphoenix&page=ibp_idpl. + * + * Software distributed under the License is distributed AS IS, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. + * See the License for the specific language governing rights + * and limitations under the License. + * + * The Original Code was created by Alexander Peshkoff + * for the Firebird Open Source RDBMS project. + * + * Copyright (c) 2007 Alexander Peshkoff + * and all contributors signed below. + * + * All Rights Reserved. + * Contributor(s): ______________________________________. + */ + +#include "firebird.h" +#include "../../common/classes/semaphore.h" +#include "../../common/classes/alloc.h" + +#ifdef MIXED_SEMAPHORE_AND_FILE_HANDLE + +/* +There is a problem with values returned by sem_open() in MacOS 10.5 and earlier. +They are not pointers. They are handles, in format of file handle (0,1,2,3,...), +and worse - they share same space with actual file handles. And when we close +unneeded file handles in divorce_terminal(), we kill all global semaphores. +MIXED_SEMAPHORE_AND_FILE_HANDLE exists to avoid it. +*/ + +#include + +namespace Firebird { + +SignalSafeSemaphore* SignalSafeSemaphore::initialList = 0; +bool SignalSafeSemaphore::divorceDone = false; + +void SignalSafeSemaphore::linkToInitialList() +{ + if (divorceDone) + { + return; + } + + unsigned int n = (U_IPTR) sem; + if (n < NOFILE) + { + next = initialList; + initialList = this; + } + else + { + next = 0; + } +} + +bool SignalSafeSemaphore::checkHandle(int n) +{ + divorceDone = true; + + for (SignalSafeSemaphore* cur = initialList; cur; cur = cur->next) + { + if (((IPTR) (cur->sem)) == n) + { + return true; + } + } + + return false; +} + +} // namespace Firebird + +#endif // MIXED_SEMAPHORE_AND_FILE_HANDLE diff --git a/src/common/classes/semaphore.h b/src/common/classes/semaphore.h index 6654e76405..e5d7d252c5 100644 --- a/src/common/classes/semaphore.h +++ b/src/common/classes/semaphore.h @@ -29,6 +29,7 @@ #ifndef CLASSES_SEMAPHORE_H #define CLASSES_SEMAPHORE_H +#include "../jrd/gdsassert.h" #ifdef WIN_NT // Note: Windows does not need signal safe version of the class @@ -81,9 +82,15 @@ public: #include #include +#include #ifndef WORKING_SEM_INIT #include +#if defined(DARWIN) +#ifdef SUPERSERVER +#define MIXED_SEMAPHORE_AND_FILE_HANDLE #endif +#endif +#endif //WORKING_SEM_INIT namespace Firebird { @@ -98,9 +105,18 @@ private: sem_t sem[1]; #else sem_t* sem; +#ifdef MIXED_SEMAPHORE_AND_FILE_HANDLE + static bool divorceDone; + static SignalSafeSemaphore* initialList; + void linkToInitialList(); + SignalSafeSemaphore* next; #endif +#endif //WORKING_SEM_INIT bool init; public: +#ifdef MIXED_SEMAPHORE_AND_FILE_HANDLE + static bool SignalSafeSemaphore::checkHandle(int n); +#endif SignalSafeSemaphore() : init(false) { @@ -110,10 +126,17 @@ public: } #else sem = sem_open(semName, O_CREAT | O_EXCL, 0700, 0); +#if defined(DARWIN) && defined(__ppc__) + if (sem == (sem_t*)SEM_FAILED) { +#else if (sem == SEM_FAILED) { +#endif system_call_failed::raise("sem_open"); } sem_unlink(semName); +#ifdef MIXED_SEMAPHORE_AND_FILE_HANDLE + linkToInitialList(); +#endif #endif init = true; } diff --git a/src/jrd/divorce.cpp b/src/jrd/divorce.cpp index b3eafe5bf7..0784ed6c55 100644 --- a/src/jrd/divorce.cpp +++ b/src/jrd/divorce.cpp @@ -52,6 +52,7 @@ #include "firebird.h" #include "../jrd/common.h" #include "../jrd/divorce.h" +#include "../common/classes/semaphore.h" #ifdef _AIX #include @@ -96,13 +97,23 @@ void divorce_terminal(int mask) * process. Close all files except for marked by the input mask. * **************************************/ - int s, fid; + int fid; /* Close all files other than those explicitly requested to stay open */ for (fid = 0; fid < NOFILE; fid++) + { +#ifdef MIXED_SEMAPHORE_AND_FILE_HANDLE + if (Firebird::SignalSafeSemaphore::checkHandle(fid)) + { + continue; + } +#endif if (!(mask & (1 << fid))) - s = close(fid); + { + close(fid); + } + } #ifdef SIGTTOU /* ignore all the teminal related signal if define */ @@ -118,8 +129,8 @@ void divorce_terminal(int mask) fid = open("/dev/tty", 2); if (fid >= 0) { - s = ioctl(fid, TIOCNOTTY, 0); - s = close(fid); + ioctl(fid, TIOCNOTTY, 0); + close(fid); } #endif @@ -128,13 +139,13 @@ void divorce_terminal(int mask) #ifdef HAVE_SETPGRP #ifdef SETPGRP_VOID - s = setpgrp(); + setpgrp(); #else - s = setpgrp(0, 0); + setpgrp(0, 0); #endif /* SETPGRP_VOID */ #else #ifdef HAVE_SETPGID - s = setpgid(0, 0); + setpgid(0, 0); #endif /* HAVE_SETPGID */ #endif /* HAVE_SETPGRP */ } diff --git a/src/remote/inet_server.cpp b/src/remote/inet_server.cpp index 5b5b451d5c..2110fe5585 100644 --- a/src/remote/inet_server.cpp +++ b/src/remote/inet_server.cpp @@ -590,11 +590,15 @@ static THREAD_ENTRY_DECLARE shutdown_thread(THREAD_ENTRY_PARAM arg) { TEXT buffer[1024]; const ISC_STATUS* vector = e.value(); - if (! (vector && fb_interpret(buffer, sizeof(buffer), &vector))) + if (e.status_known() && (vector = e.value()) && + fb_interpret(buffer, sizeof(buffer), &vector)) { - strcpy(buffer, "Unknown failure in semaphore::enter()"); + gds__log_status("(shutdown thread)", e.value()); + } + else + { + gds__log("Unknown failure in shutdown thread in shutSem.enter()", 0); } - gds__log(buffer, 0); exit(0); } if (! alreadyClosing)