From 555375b4e53a0557db2cf293168537690b09901f Mon Sep 17 00:00:00 2001 From: mcorino Date: Wed, 25 Aug 2010 09:51:01 +0000 Subject: Wed Aug 25 09:49:41 UTC 2010 Martin Corino * ace/Arg_Shifter.h: * ace/config-macosx-leopard.h: * ace/Guard_T.h: * ace/Global_Macros.h: Selected changes from patches in Bugzilla 3652. --- ACE/ChangeLog | 8 ++++++++ ACE/ace/Arg_Shifter.h | 25 +++++++++++++++++++------ ACE/ace/Global_Macros.h | 41 +++++++++++++++++++++++++++++++++++++++++ ACE/ace/Guard_T.h | 31 +++++++++++++++++++++++++++++-- ACE/ace/config-macosx-leopard.h | 2 +- 5 files changed, 98 insertions(+), 9 deletions(-) diff --git a/ACE/ChangeLog b/ACE/ChangeLog index 499751297f5..d5ab5366c6b 100644 --- a/ACE/ChangeLog +++ b/ACE/ChangeLog @@ -1,3 +1,11 @@ +Wed Aug 25 09:49:41 UTC 2010 Martin Corino + + * ace/Arg_Shifter.h: + * ace/config-macosx-leopard.h: + * ace/Guard_T.h: + * ace/Global_Macros.h: + Selected changes from patches in Bugzilla 3652. + Tue Aug 24 14:21:01 UTC 2010 Johnny Willemsen * ace/OS_NS_Thread.h: diff --git a/ACE/ace/Arg_Shifter.h b/ACE/ace/Arg_Shifter.h index 8439e92ef51..ba5703ce89c 100644 --- a/ACE/ace/Arg_Shifter.h +++ b/ACE/ace/Arg_Shifter.h @@ -33,13 +33,23 @@ ACE_BEGIN_VERSIONED_NAMESPACE_DECL * @a argv vector, so deeper levels of argument parsing can locate the yet * unprocessed arguments at the beginning of the vector. * + * Nomenclature: + * argument - a member of the argv array + * option - an argument starting with '-' + * flag - synonym for "option" + * parameter value - an argument not starting with '-' + * parameter - synonym for "parameter value" + * * The @c ACE_Arg_Shifter copies the pointers of the @a argv vector - * into a temporary array. As the @c ACE_Arg_Shifter iterates over - * the copied vector, it places known arguments in the rear of the - * vector, leaving the unknown ones in the beginning. So, after having - * visited all the arguments in the temporary vector, @c ACE_Arg_Shifter - * has placed all the unknown arguments in their original order at - * the front of original @a argv. + * into a temporary array, emptying the original. As the @c ACE_Arg_Shifter + * iterates over the temporary array, it places known arguments in the rear + * of the original array and places the unknown ones in the beginning of the + * original array. It modifies argc to be the number of unknown arguments, + * so it looks to the caller as if the original array contains only unknown + * arguments. So, after @c ACE_Arg_Shifter has visited all the arguments + * in the temporary array, the original @a argv array appears to contain + * only the unknown arguments in their original order (but it actually has + * all the known arguments, too, beyond argc). */ template class ACE_Arg_Shifter_T @@ -202,6 +212,9 @@ private: /// The index of in which we'll stick the next known /// argument. int front_; + /* This is not really the "front" at all. It's the point after + * which the unknown arguments end and at which the known arguments begin. + */ }; typedef ACE_Arg_Shifter_T ACE_Arg_Shifter; diff --git a/ACE/ace/Global_Macros.h b/ACE/ace/Global_Macros.h index fa1f2c69283..cce114df09e 100644 --- a/ACE/ace/Global_Macros.h +++ b/ACE/ace/Global_Macros.h @@ -108,6 +108,16 @@ ACE_END_VERSIONED_NAMESPACE_DECL // Convenient macro for testing for deadlock, as well as for detecting // when mutexes fail. +/* WARNING: + * Use of ACE_GUARD() is rarely correct. ACE_GUARD() causes the current + * function to return if the lock is not acquired. Since merely returning + * (no value) almost certainly fails to handle the acquisition failure + * and almost certainly fails to communicate the failure to the caller + * for the caller to handle, ACE_GUARD() is almost always the wrong + * thing to do. The same goes for ACE_WRITE_GUARD() and ACE_READ_GUARD() . + * ACE_GUARD_REACTION() is better because it lets you specify error + * handling code. + */ #define ACE_GUARD_ACTION(MUTEX, OBJ, LOCK, ACTION, REACTION) \ ACE_Guard< MUTEX > OBJ (LOCK); \ if (OBJ.locked () != 0) { ACTION; } \ @@ -133,6 +143,37 @@ ACE_END_VERSIONED_NAMESPACE_DECL // ---------------------------------------------------------------- +#if defined(ACE_UNEXPECTED_RETURNS) + +/* Using ACE_UNEXPECTED_RETURNS is ill-advised because, in many cases, + * it fails to inform callers of the error condition. + * It exists mainly to provide back-compatibility with old, dangerous, + * incorrect behavior. + * Code that previously used ACE_GUARD() or ACE_GUARD_RETURN() to return + * upon failure to acquire a lock can now use: + * ACE_GUARD_REACTION(..., ACE_UNEXPECTED(...)) + * The behavior of this depends on whether or not ACE_UNEXPECTED_RETURNS + * is defined. If so, it just returns upon failure (as in the original), + * which is usually dangerous because it usually fails to handle the + * error. If not, it calls std::unexpected(), which does whatever the + * std::unexpected handler does (which is to abort, by default). + */ +# define ACE_UNEXPECTED(RETVAL) \ + do { \ + return RETVAL; \ + } while (0) + +#else + +# define ACE_UNEXPECTED(RETVAL) \ + do { \ + std::unexpected(); \ + } while (0) + +#endif + +// ---------------------------------------------------------------- + # define ACE_DES_NOFREE(POINTER,CLASS) \ do { \ if (POINTER) \ diff --git a/ACE/ace/Guard_T.h b/ACE/ace/Guard_T.h index 1780f8fd1bf..26a7e9441ef 100644 --- a/ACE/ace/Guard_T.h +++ b/ACE/ace/Guard_T.h @@ -31,12 +31,35 @@ ACE_BEGIN_VERSIONED_NAMESPACE_DECL * @class ACE_Guard * * @brief This data structure is meant to be used within a method or - * function... It performs automatic aquisition and release of + * function... It performs automatic acquisition and release of * a parameterized synchronization object ACE_LOCK. * - * The class given as an actual parameter must provide at + * The class given as an actual parameter must provide, at * the very least the , , , and * methods. + * + * WARNING: A successfully constructed ACE_Guard does NOT mean that the + * lock was acquired! It is the caller's responsibility, after + * constructing an ACE_Guard, to check whether the lock was successfully + * acquired. Code like this is dangerous: + * { + * ACE_Guard g(lock); + * ... perform critical operation requiring lock to be held ... + * } + * Instead, one must do something like this: + * { + * ACE_Guard g(lock); + * if (! g.locked()) + * { + * ... handle error ... + * } + * else + * { + * ... perform critical operation requiring lock to be held ... + * } + * } + * The ACE_GUARD_RETURN() and ACE_GUARD_REACTION() macros are designed to + * to help with this. */ template class ACE_Guard @@ -114,6 +137,8 @@ private: * acquires/releases a write lock automatically (naturally, the * it is instantiated with must support the appropriate * API). + * + * WARNING: See important "WARNING" in comments at top of ACE_Guard. */ template class ACE_Write_Guard : public ACE_Guard @@ -158,6 +183,8 @@ public: * acquires/releases a read lock automatically (naturally, the * it is instantiated with must support the appropriate * API). + * + * WARNING: See important "WARNING" in comments at top of ACE_Guard. */ template class ACE_Read_Guard : public ACE_Guard diff --git a/ACE/ace/config-macosx-leopard.h b/ACE/ace/config-macosx-leopard.h index 9cc7c3b8cdd..3260edbdad7 100644 --- a/ACE/ace/config-macosx-leopard.h +++ b/ACE/ace/config-macosx-leopard.h @@ -228,4 +228,4 @@ #error "Compiler must be upgraded, see http://developer.apple.com" #endif /* __APPLE_CC__ */ -#endif /* ACE_CONFIG_MACOSX_TIGER_H */ +#endif /* ACE_CONFIG_MACOSX_LEOPARD_H */ -- cgit v1.2.1