zoukankan      html  css  js  c++  java
  • 第3月第2天 find symbolicatecrash 生产者-消费者 ice 引用计数

    1.linux find export

    find /Applications/Xcode.app/ -name symbolicatecrash -type f

    export DEVELOPER_DIR="/Applications/Xcode.app/Contents/Developer"

     

    2.symbolicatecrash

    http://www.cnblogs.com/ningxu-ios/p/4141783.html

    3.AURenderCallbackStruct

            AURenderCallbackStruct callbackStruct;
            callbackStruct.inputProc = AudioPlayUnit_context::playbackCallback;
            callbackStruct.inputProcRefCon = this;

    4.生产者-消费者

    1)缓冲区,缓冲区写满需等待,消费者消费后需通知

    class BytesBuffer : public IceUtil::Shared
    {
    public:
        BytesBuffer(size_t bufferSize);
        void feed(size_t size, BufferChunkRef cbChunk);
        void eat(size_t size, BufferChunkRef cbChunk);

    等待 

    void BytesBuffer_context::feed(size_t size, BufferChunkRef cbChunk)
    {
        {
            Monitor<RecMutex>::Lock lock(_monitor);
            if (_feedTerminated) return;
            
            while( size > _feedCapacity && !_eatTerminated) {
                _currentFeedRequestSize = size;
                //            SP::printf("
    wait feeding, eatting %s
    ", _eatTerminated ? "terminated" : "not terminated");
                _monitor.wait();
            }
            _currentFeedRequestSize = 0;
        }

    通知

            Monitor<RecMutex>::Lock lock(_monitor);
            //check and notify, if _feedTerminated then _currentFeedRequestSize=0,  verify already included
            if (_feedCapacity < _currentFeedRequestSize && _feedCapacity + size >= _currentFeedRequestSize)
                _monitor.notify();
    

      

    2)生产者

    DecoderFileThread::DecoderFileThread(const char* path, BytesBufferPtr buffer)
    : filepath(path)
    , _buffer(buffer)
    , _destroy(false)
    , _decodeState(0)
    
    , file(0)
    {
        _cbChunk._userData = this;
        _cbChunk._callback = DecoderFileThread::feedCallback;
    }
    
    void DecoderFileThread::run()
    {
        _decodeState = Decoder_Interface_init();
        file = fopen(filepath.c_str(), "rb");
        fseek(file, 6, 0);
        do {
            _buffer->feed(160*2, &_cbChunk);
        } while (!_destroy);
        Decoder_Interface_exit(_decodeState);
        fclose(file);
        //SP::printf("
    finish decode file
    ");
    }

    3)消费者

    OSStatus AudioPlayUnit_context::playbackCallback(void *inRefCon,
                                                     AudioUnitRenderActionFlags *ioActionFlags,
                                                     const AudioTimeStamp *inTimeStamp,
                                                     UInt32 inBusNumber,
                                                     UInt32 inNumberFrames,
                                                     AudioBufferList *ioData) {
    #if !TEST
        // Notes: ioData contains buffers (may be more than one!)
        // Fill them up as much as you can. Remember to set the size value in each buffer to match how
        // much data is in the buffer.
        AudioPlayUnit_context* This = (AudioPlayUnit_context*)inRefCon;
        
        
        RenderChunk cbchunk = {0};
        cbchunk.inRefCon = This;
        cbchunk.ioActionFlags = ioActionFlags;
        cbchunk.inTimeStamp = inTimeStamp;
        cbchunk.inBusNumber = inBusNumber;
        cbchunk.inNumberFrames = inNumberFrames;
        cbchunk.ioData = ioData;
        
        BufferChunk chunk;
        chunk._callback = AudioPlayUnit_context::eatCallback;
        chunk._userData = &cbchunk;
        This->_buffer->eat(inNumberFrames*This->_audioFormat.mBytesPerFrame, &chunk);
        
        static size_t expired = 0;
        static IceUtil::Time lasttime;
        if(This->_renderstartTimestamp == 0)
        {
            This->_renderstartTimestamp = IceUtil::Time::now().toMilliSeconds();
            expired = 0;
        }
        else
            expired = IceUtil::Time::now().toMilliSeconds() - This->_renderstartTimestamp;
        
        if (This->_listenerPtr.get()) This->_listenerPtr->progress(This->_listenerPtr->userData, expired);
        return noErr;
    #else
        
        AudioPlayUnit_context* This = (AudioPlayUnit_context*)inRefCon;
        static size_t pos = 0;
        ioData->mBuffers[0].mData = This->_filebuffer + pos;
        pos += inNumberFrames*2;
        //bytes2HexS((unsigned char*)ioData->mBuffers[0].mData, inNumberFrames*2);
        return noErr;
    #endif
    }

     5.ice

    unix网络编程(卷2)7.3小节描述了生产者-消费者问题,7.5小节描述了条件变量

    iceutil的monitor就是cpp的封装实现。

    //
    // This monitor implements the Mesa monitor semantics. That is any
    // calls to notify() or notifyAll() are delayed until the monitor is
    // unlocked.
    //
    template <class T>
    class Monitor
    {

     6.引用计数

    objective-c的引用计数很好理解,[[xx alloc] init]引用计数为1,retain引用计数加1,release引用计数减1,当引用计数为0时销毁内存。

    ice的IceUtil::Shared包含了引用计数加1减1,但IceUtil::Shared在构造函数和析构函数并不会改变引用计数。使用时是使用IceUtil::Handle对象,IceUtil::Handle包含一个_ptr,构造函数如果参数为空,_prt置为null。如果构造函数的参数不为空,就会将_prt的引用计数加1,this->_ptr->__incRef(),析构函数会将_ptr的引用计数减1,this->_ptr->__decRef()。decRef函数判断引用计数为0时销毁内存。

    IceUtril::Handle的拷贝构造函数和赋值函数也是将_ptr引用计数加1.因此有多个IceHandle包含同一个IceUtil::Shared,将IceUtil::Shared的引用计数加加减减。

    IceUtil::Shared是用户自己new出来的,默认的引用计数为0,使用IceUtil::Handle时才会改变_ptr引用计数的值。

    ace的ACE_Refcounted_Auto_Ptr_Rep包含了引用计数,内部包括一个auto_ptr的ptr_对象,构造函数会创建ptr_对象,析构时ptr_对象也会自动销毁,auto_ptr对象销毁时会释放new出来的内存。通过static函数attach,detach将引用计数加1减1,detach函数判断引用计数为0时销毁ACE_Refcounted_Auto_Ptr_Rep对象。

    ace使用时是使用 ACE_Refcounted_Auto_Ptr,ACE_Refcounted_Auto_Ptr对象构造函数会创建ACE_Refcounted_Auto_Ptr_Rep对象rep_,析构函数会调用detach函数将rep_的引用计数减1.ACE_Refcounted_Auto_Ptr对象的拷贝构造函数和赋值函数也是将rep_引用计数加1.

    因此有多个ACE_Refcounted_Auto_Ptr包含同一个ACE_Refcounted_Auto_Ptr_Rep,将ACE_Refcounted_Auto_Ptr_Rep的引用计数加加减减。

    ACE_Refcounted_Auto_Ptr_Rep对象是ACE_Refcounted_Auto_Ptr对象构造函数创建的。使用ACE_Refcounted_Auto_Ptr时会改变rep_引用计数的值。

    总结:

    ace的ACE_Refcounted_Auto_Ptr不是很好理解,因为X *p并没有引用计数,所以需要封装一个ACE_Refcounted_Auto_Ptr_Rep对象,但ACE_Refcounted_Auto_Ptr_Rep对象又不是用户自己创建的,是构造函数自己创建的。 而构造函数中又没有通过ACE_Refcounted_Auto_Ptr_Rep对象来创建,这样就隐藏了ACE_Refcounted_Auto_Ptr_Rep对象的存在,让人不好理解。

    第一步,创建ACE_Refcounted_Auto_Ptr_Rep对象,第二步使用ACE_Refcounted_Auto_Ptr。ace不让用户一步步完成。构造函数是通过X *p创建ACE_Refcounted_Auto_Ptr_Rep对象,拷贝构造函数和赋值函数是通过const ACE_Refcounted_Auto_Ptr<X, ACE_LOCK> &r的rep_引用计数加1。

    而ice 因此如果需要将一个对象申明智能指针,必须让其继承至IceUtil::Shared,就好理解一点。

    iceutil::Shared

    class ICE_UTIL_API Shared
    {
    public:
    
        Shared();
        Shared(const Shared&);
    
        virtual ~Shared()
        {
        }
    
        Shared& operator=(const Shared&)
        {
            return *this;
        }
    
        virtual void __incRef();
        virtual void __decRef();
        virtual int __getRef() const;
        virtual void __setNoDelete(bool);
    
    protected:
    
    #if defined(_WIN32)
        LONG _ref;
    #elif defined(ICE_HAS_ATOMIC_FUNCTIONS) || defined(ICE_HAS_GCC_BUILTINS)
        volatile int _ref;
    #else
        int _ref;
        Mutex _mutex;
    #endif
        bool _noDelete;
    };
    
    }

    ace

    template <class X, class ACE_LOCK> inline
    ACE_Refcounted_Auto_Ptr<X, ACE_LOCK>::ACE_Refcounted_Auto_Ptr (X *p)
      : rep_ (AUTO_REFCOUNTED_PTR_REP::create (p))
    {
    }
    
    template <class X, class ACE_LOCK> inline
    ACE_Refcounted_Auto_Ptr<X, ACE_LOCK>::ACE_Refcounted_Auto_Ptr (const ACE_Refcounted_Auto_Ptr<X, ACE_LOCK> &r)
      : rep_ (AUTO_REFCOUNTED_PTR_REP::attach (((ACE_Refcounted_Auto_Ptr<X, ACE_LOCK> &) r).rep_))
    {
    }
    
    template <class X, class ACE_LOCK> inline void
    ACE_Refcounted_Auto_Ptr<X, ACE_LOCK>::operator = (const ACE_Refcounted_Auto_Ptr<X, ACE_LOCK> &rhs)
    {
      //  bind <this> to the same <ACE_Refcounted_Auto_Ptr_Rep> as <r>.
      AUTO_REFCOUNTED_PTR_REP *old_rep = this->rep_;
      if (rhs.rep_ != 0)
        {
          this->rep_ = AUTO_REFCOUNTED_PTR_REP::attach
            (const_cast<ACE_Refcounted_Auto_Ptr<X, ACE_LOCK>& > (rhs).rep_);
          if (this->rep_ != 0)
            AUTO_REFCOUNTED_PTR_REP::detach (old_rep);
        }
      else    // Assign a 0 rep to this
        {
          AUTO_REFCOUNTED_PTR_REP::detach (old_rep);
          this->rep_ = 0;
        }
    }
    
    template <class X, class ACE_LOCK>
    ACE_Refcounted_Auto_Ptr<X, ACE_LOCK>::~ACE_Refcounted_Auto_Ptr (void)
    {
      AUTO_REFCOUNTED_PTR_REP::detach (rep_);
    }

    7.书籍

    http://bestcbooks.com/recommended-cpp-books/

  • 相关阅读:
    手机游戏怎么独占世界手游鳌头
    游戏开发商是如何做到每日进帐410万美元的?
    [手游新项目历程]-48-svn分支开发与主干合并
    三国武将所带兵种
    Supercell:靠两款手游如何做到30亿美金市值?
    理财投资这需要知道的50个真相
    [手游新项目历程]-49-性能分析
    [手游新项目历程]-50-Mysql的大字段问题(数据库执行错误: Error=1118, Reason=Row size too large (> 8126))
    三国杀
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
  • 原文地址:https://www.cnblogs.com/javastart/p/6124653.html
Copyright © 2011-2022 走看看