mxmSmartHandle.h

00001 //           ///          //                                  C++ Cross Platform
00002 //          /////        ////
00003 //         /// XXX     XXX ///            ///////////   /////////     ///   ///
00004 //        ///    XXX XXX    ///         ///             ///    ///   ///  ///
00005 //       ///       XXX       ///         /////////     ///      //  //////
00006 //      ///      XXX XXX      ///               ///   ///    ///   ///  ///
00007 //     ////    XXX     XXX    ////    ////////////  //////////    ///   ///
00008 //    ////                     ////
00009 //   ////  M  O  B  O  T  I  X  ////////////////////////////////////////////////
00010 //  //// Security Vision Systems //////////////////////////////////////////////
00011 //
00012 //  $Author: khe_admin $
00013 //  $LastChangedBy: khe_admin $
00014 //  $LastChangedDate: 2007-06-29 12:31:37 +0200 (Fri, 29 Jun 2007) $
00015 //  $HeadURL: http://svn.mobotix.net/svn/mxsdk/src/mxm/trunk/include/mxm/core/mxmSmartHandle.h $
00016 //
00018      //
00019      //  MOBOTIX MxPEG SDK
00020      //
00021      //  This file belongs to the C++ library released as part of the MxPEG SDK.
00022      //
00023      //  This software is licenced under the BSD licence,
00024      //  http://www.opensource.org/licenses/bsd-license.php
00025      //
00026      //  Copyright (c) 2005 - 2007, MOBOTIX AG
00027      //  All rights reserved.
00028      //
00029      //  Redistribution and use in source and binary forms, with or without
00030      //  modification, are permitted provided that the following conditions are
00031      //  met:
00032      //
00033      //  - Redistributions of source code must retain the above copyright
00034      //    notice, this list of conditions and the following disclaimer.
00035      //
00036      //  - Redistributions in binary form must reproduce the above copyright
00037      //    notice, this list of conditions and the following disclaimer in the
00038      //    documentation and/or other materials provided with the distribution.
00039      //
00040      //  - Neither the name of MOBOTIX AG nor the names of its contributors may
00041      //    be used to endorse or promote products derived from this software
00042      //    without specific prior written permission.
00043      //
00044      //  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00045      //  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00046      //  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
00047      //  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
00048      //  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00049      //  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00050      //  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00051      //  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00052      //  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00053      //  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00054      //  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00055      //
00057 
00058 
00059 
00060 #ifndef __MXM_SMARTHANDLE_H__
00061 #define __MXM_SMARTHANDLE_H__
00062 
00063 
00064 
00065 #include <mxm/core/mxmLockInterface.h>
00066 #include <mxm/core/mxmSmartHandleCore.h>
00067 
00068 
00069 
00070 namespace mxm {
00071   
00074 
00341   template<class T> class smart : public mxmSmartHandleCore {
00342     
00343    public:
00346     smart();
00348     smart(const smart<T> &other);
00351     smart(T *handlee);
00353     ~smart();
00354     
00355    public:
00357     smart<T> &operator=(const smart<T> &other);
00359     smart<T> &operator=(T *handlee);
00361     T *operator->(void) const;
00363     T &operator*(void) const;
00365     bool operator==(const smart<T> &other) const;
00370     template<class NewT>
00371     operator smart<NewT>(void) const;
00372     
00373    private:
00375     void deleteHandlee(void);
00376   };
00377 
00378 };   // namespace _mxm_
00379 
00380 
00381 
00382 template<class T>
00383 mxm::smart<T>::smart() {
00384   
00385 }
00386 
00387 
00388 template<class T>
00389 mxm::smart<T>::smart(const smart<T> &other) {
00390   
00391   joinGroup(other);
00392 }
00393 
00394 
00395 template<class T> 
00396 mxm::smart<T>::smart(T *handlee) {
00397   
00398   Handlee = static_cast<void *>(handlee);   // OK, if _0_ (= no effect)
00399 }
00400 
00401 
00402 template<class T> 
00403 mxm::smart<T>::~smart() {
00404   
00405   // kills potential handlee and lock stuff...
00406   reset();
00407                      // this should have been called by the mxmSmartHandleCore
00408                      // destructor - however, since it calls the virtual method
00409                      // deleteHandlee(), the latter would then not be correctly
00410                      // activated due to virtual function invocation working
00411                      // differently when triggered directly or indirectly from a
00412                      // destructor
00413 }
00414 
00415 
00416 
00421 template<class T>
00422 mxm::smart<T> &mxm::smart<T>::operator=(const smart<T> &other) {
00423   
00424   reset();
00425   
00426   // NOTE : synchronization breach: problem here is
00427   // - there are potentially two locks involved
00428   // - the handle is temporarily unprotected
00429   // Scenario of pain: Another thread can now read Lock==0 as part of some
00430   // handle operation and decide that the handle (group) is unprotected.
00431   // <preempt> We join another protected handle group by calling joinGroup()
00432   // below and link into the group's doublelinked ring structure. <preempt> The
00433   // other thread resumes its operation and modifies the same ring structure
00434   // without having acquired the lock. Very unfortunate situation.
00435   
00436   joinGroup(other);
00437   
00438   return(*this);
00439 }
00440 
00441 
00446 template<class T>
00447 mxm::smart<T> &mxm::smart<T>::operator=(T *handlee) {
00448   
00449   reset();
00450   
00451   Handlee = static_cast<void *>(handlee);   // OK, if _0_ (= no effect)
00452   
00453   // NOTE : synchronization breach possible: a potential previous lock
00454   //        protection has just been removed by reset(). If later on the handle
00455   //        joins another protected handle group, the process as a whole is a
00456   //        transition from one lock protection space to another, with a
00457   //        temporary lack of protection in between, just like the
00458   //        operator=(const smart<T> &other) assignment above.
00459   
00460   return(*this);
00461 }
00462 
00463 
00464 template<class T>
00465 T *mxm::smart<T>::operator->(void) const {
00466   
00467   return(static_cast<T *>(Handlee));
00468 }
00469 
00470 
00471 template<class T>
00472 T &mxm::smart<T>::operator*(void) const {
00473   
00474   return(*static_cast<T *>(Handlee));
00475 }
00476 
00477 
00478 template<class T>
00479 bool mxm::smart<T>::operator==(const mxm::smart<T> &other) const {
00480   
00481   return(Handlee == other.Handlee);
00482 }
00483 
00484 
00491 template<class T>
00492 template<class NewT>
00493 mxm::smart<T>::operator mxm::smart<NewT>(void) const {
00494   
00495   smart<NewT> new_handle;   // creates deafult state handle
00496   
00497   if(Lock) Lock->acquire();   // -----------------------------------------------
00498   
00499   NewT *new_type = dynamic_cast<NewT *>(static_cast<T *>(Handlee));
00500   
00501   if(new_type) new_handle.joinGroup(*this,
00502                                     static_cast<void *>(new_type),
00503                                     true);
00504                                 // _true_ => don't synchronize, already did that
00505   
00506   if(Lock) Lock->release();   // -----------------------------------------------
00507   
00508   return(new_handle);
00509 }
00510 
00511 
00512 template<class T>
00513 void mxm::smart<T>::deleteHandlee(void) {
00514   
00515   delete static_cast<T *>(Handlee);
00516 }
00517 
00518 
00519 
00520 #endif   // __MXM_SMARTHANDLE_H__

Generated on Fri Jun 29 17:21:04 2007 for MxPEG SDK by  doxygen 1.4.6