Sptr.cxx
上传用户:sy_wanhua
上传日期:2013-07-25
资源大小:3048k
文件大小:8k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

C/C++

  1. /* ====================================================================
  2.  * The Vovida Software License, Version 1.0 
  3.  * 
  4.  * Copyright (c) 2000 Vovida Networks, Inc.  All rights reserved.
  5.  * 
  6.  * Redistribution and use in source and binary forms, with or without
  7.  * modification, are permitted provided that the following conditions
  8.  * are met:
  9.  * 
  10.  * 1. Redistributions of source code must retain the above copyright
  11.  *    notice, this list of conditions and the following disclaimer.
  12.  * 
  13.  * 2. Redistributions in binary form must reproduce the above copyright
  14.  *    notice, this list of conditions and the following disclaimer in
  15.  *    the documentation and/or other materials provided with the
  16.  *    distribution.
  17.  * 
  18.  * 3. The names "VOCAL", "Vovida Open Communication Application Library",
  19.  *    and "Vovida Open Communication Application Library (VOCAL)" must
  20.  *    not be used to endorse or promote products derived from this
  21.  *    software without prior written permission. For written
  22.  *    permission, please contact vocal@vovida.org.
  23.  *
  24.  * 4. Products derived from this software may not be called "VOCAL", nor
  25.  *    may "VOCAL" appear in their name, without prior written
  26.  *    permission of Vovida Networks, Inc.
  27.  * 
  28.  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
  29.  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  30.  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
  31.  * NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL VOVIDA
  32.  * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
  33.  * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
  34.  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  35.  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  36.  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
  37.  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  38.  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
  39.  * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
  40.  * DAMAGE.
  41.  * 
  42.  * ====================================================================
  43.  * 
  44.  * This software consists of voluntary contributions made by Vovida
  45.  * Networks, Inc. and many individuals on behalf of Vovida Networks,
  46.  * Inc.  For more information on Vovida Networks, Inc., please see
  47.  * <http://www.vovida.org/>.
  48.  *
  49.  */
  50. static const char* const Sptr_cxx_Version =
  51.     "$Id: Sptr.cxx,v 1.10 2001/04/27 11:02:51 bko Exp $";
  52. #include "Sptr.hxx"
  53. #ifdef __linux__
  54. #include <execinfo.h>
  55. #endif
  56. #include <stdio.h>
  57. #define SPTR_TRACEBACK_RUNNING 0
  58. /// this C file is only used for debugging, so it is totally ifdef'ed
  59. #define SPTR_DEBUG_ACTIVE 0
  60. #if SPTR_DEBUG
  61. // static item
  62. SptrDebugger* SptrDebugger::impl_ = 0;
  63. SptrDebugger::SptrDebugger()
  64.         : ptrsInUse(),
  65.         mutex()
  66. {}
  67. SptrDebugger* SptrDebugger::getInstance()
  68. {
  69.     if (!impl_)
  70.     {
  71.         impl_ = new SptrDebugger;
  72.     }
  73.     assert(impl_);
  74.     return impl_;
  75. }
  76. void SptrDebugger::newPtr(void* ptr)
  77. {
  78. #if SPTR_DEBUG_ACTIVE
  79.     if (ptr == 0)
  80.     {
  81.         // do nothing for the null ptr.
  82.         return ;
  83.     }
  84.     PtrMap::iterator i;
  85.     getInstance()->mutex.lock();
  86.     i = getInstance()->ptrsInUse.find(ptr);
  87.     if (i != getInstance()->ptrsInUse.end())
  88.     {
  89.         // check to see if it's set to inUse
  90.         if (i->second)
  91.         {
  92.             cerr << "pointer " << ptr
  93.             << " already in a different Sptr" << endl;
  94.             assert(0);
  95.         }
  96.     }
  97.     getInstance()->ptrsInUse[ptr] = true;
  98.     getInstance()->mutex.unlock();
  99. #endif
  100. }
  101. void SptrDebugger::deletePtr(void* ptr)
  102. {
  103. #if SPTR_DEBUG_ACTIVE
  104.     PtrMap::iterator i;
  105.     getInstance()->mutex.lock();
  106.     i = getInstance()->ptrsInUse.find(ptr);
  107.     if (i == getInstance()->ptrsInUse.end())
  108.     {
  109.         cerr << "pointer " << ptr
  110.         << " is not in any Sptr" << endl;
  111.         assert(0);
  112.     }
  113.     else
  114.     {
  115.         if (i->second == false)
  116.         {
  117.             cerr << "pointer " << ptr
  118.             << " was already deleted by another Sptr" << endl;
  119.             assert(0);
  120.         }
  121.         else
  122.         {
  123.             getInstance()->ptrsInUse[ptr] = false;
  124.         }
  125.     }
  126.     getInstance()->mutex.unlock();
  127. #endif
  128. }
  129. #endif
  130. #if SPTR_TRACEBACK
  131. #if SPTR_TRACEBACK_RUNNING
  132. #ifdef __linux__
  133. class SptrTraceback
  134. {
  135.     public:
  136.         SptrTraceback();
  137.         SptrTraceback(const SptrTraceback& x);
  138.         SptrTraceback(void* sptr);
  139.         bool operator==(const SptrTraceback& x) const;
  140.         SptrTraceback& operator=(const SptrTraceback& x);
  141.         void dump(FILE* f);
  142.     private:
  143.         void* sptr;
  144.         void *my_backtrace[50];
  145.         int backtrace_size;
  146. };
  147. SptrTraceback::SptrTraceback()
  148.         : sptr(0),
  149.         backtrace_size(0)
  150. {
  151. }
  152. SptrTraceback::SptrTraceback(const SptrTraceback& x)
  153.         : sptr(x.sptr),
  154.         backtrace_size(x.backtrace_size)
  155. {
  156.     for (int i = 0; i < backtrace_size; i++)
  157.     {
  158.         my_backtrace[i] = x.my_backtrace[i];
  159.     }
  160. }
  161. SptrTraceback::SptrTraceback(void* sptr)
  162.         : sptr(sptr),
  163.         backtrace_size(0)
  164. {
  165.     backtrace_size = backtrace(my_backtrace, 50);
  166. }
  167. bool SptrTraceback::operator==(const SptrTraceback& x) const
  168. {
  169.     return sptr == x.sptr;
  170. }
  171. SptrTraceback& SptrTraceback::operator=(const SptrTraceback& x)
  172. {
  173.     sptr = x.sptr;
  174.     backtrace_size = x.backtrace_size;
  175.     for (int i = 0; i < backtrace_size; i++)
  176.     {
  177.         my_backtrace[i] = x.my_backtrace[i];
  178.     }
  179.     return *this;
  180. }
  181. void SptrTraceback::dump(FILE* f)
  182. {
  183.     fprintf(f, "  %p:", sptr);
  184.     for (int i = 0; i < backtrace_size; i++)
  185.     {
  186.         fprintf(f, " %p", my_backtrace[i]);
  187.     }
  188.     fprintf(f, "n");
  189. }
  190. struct ptr_less : public binary_function < void*, void*, bool >
  191. {
  192.     bool operator()(void* const & x, void* const & y) const
  193.     {
  194.         return ((unsigned int) x) < ((unsigned int) y);
  195.     }
  196. };
  197. //////////////////////////////////////////////////////////////////////
  198. class SptrTracebackPack
  199. {
  200.     public:
  201.         SptrTracebackPack();
  202.         SptrTracebackPack(const SptrTracebackPack& x);
  203.         SptrTracebackPack(void* myPtr, void* sptr);
  204.         void insert(void* sptr);
  205.         void clear(void* sptr);
  206.         void dump(FILE* f);
  207.     private:
  208.         void* ptr;
  209.         map < void*, SptrTraceback, ptr_less > tracebacks;
  210. };
  211. SptrTracebackPack::SptrTracebackPack(void* myPtr, void* sptr)
  212.         : ptr(myPtr),
  213.         tracebacks()
  214. {
  215.     insert(sptr);
  216. }
  217. SptrTracebackPack::SptrTracebackPack()
  218.         : ptr(0),
  219.         tracebacks()
  220. {
  221. }
  222. SptrTracebackPack::SptrTracebackPack(const SptrTracebackPack& x)
  223.         : ptr(x.ptr),
  224.         tracebacks(x.tracebacks)
  225. {
  226. }
  227. void SptrTracebackPack::insert(void* sptr)
  228. {
  229.     SptrTraceback t(sptr);
  230.     tracebacks[sptr] = t;
  231. }
  232. void SptrTracebackPack::clear(void* sptr)
  233. {
  234.     tracebacks.erase(tracebacks.find(sptr));
  235. }
  236. void SptrTracebackPack::dump(FILE* f)
  237. {
  238.     map < void*, SptrTraceback, ptr_less > ::iterator i = tracebacks.begin();
  239.     fprintf(f, "%p>n", ptr);
  240.     while (i != tracebacks.end())
  241.     {
  242.         i->second.dump(f);
  243.         ++i;
  244.     }
  245. }
  246. typedef map < void*, SptrTracebackPack > TraceMap;
  247. static TraceMap tracemap;
  248. void sptrDebugMarkTraceback(void* sptr, void* ptr)
  249. {
  250.     TraceMap::iterator i;
  251.     if(ptr)
  252.     {
  253. i = tracemap.find(ptr);
  254. if (i != tracemap.end())
  255. {
  256.     i->second.insert(sptr);
  257. }
  258. else
  259. {
  260.     tracemap[ptr] = SptrTracebackPack(ptr, sptr);
  261. }
  262.     }
  263. }
  264. void sptrDebugClearTraceback(void* sptr, void* ptr)
  265. {
  266.     TraceMap::iterator i;
  267.     if(ptr)
  268.     {
  269. i = tracemap.find(ptr);
  270. if (i != tracemap.end())
  271. {
  272.     i->second.clear(sptr);
  273. }
  274. else
  275. {
  276.     assert(0);
  277. }
  278.     }
  279. }
  280. void sptrDebugDumpTraceback(char* filename)
  281. {
  282.     // open file, and dump
  283.     FILE* f;
  284.     f = fopen(filename, "w");
  285.     if (!f)
  286.     {
  287.         return ;
  288.     }
  289.     TraceMap::iterator i = tracemap.begin();
  290.     while (i != tracemap.end())
  291.     {
  292.         // dump the record
  293.         i->second.dump(f);
  294.         ++i;
  295.     }
  296.     fclose(f);
  297. }
  298. #else
  299. // no linux -- these functions do nothing
  300. void sptrDebugMarkTraceback(void* sptr, void* ptr)
  301. {
  302. }
  303. void sptrDebugClearTraceback(void* sptr, void* ptr)
  304. {
  305. }
  306. void sptrDebugDumpTraceback(char* filename)
  307. {
  308. }
  309. // #if __linux__
  310. #endif
  311. // #if __linux__
  312. // #if SPTR_TRACEBACK_RUNNING
  313. #else
  314. // #if SPTR_TRACEBACK_RUNNING
  315. void sptrDebugMarkTraceback(void* sptr, void* ptr)
  316. {
  317. }
  318. void sptrDebugClearTraceback(void* sptr, void* ptr)
  319. {
  320. }
  321. void sptrDebugDumpTraceback(char* filename)
  322. {
  323. }
  324. // #if SPTR_TRACEBACK_RUNNING
  325. #endif
  326. // #if SPTR_TRACEBACK_RUNNING
  327. // #if SPTR_TRACEBACK
  328. #endif
  329. // #if SPTR_TRACEBACK