hxpropwclnt.cpp
上传用户:dangjiwu
上传日期:2013-07-19
资源大小:42019k
文件大小:18k
源码类别:

Symbian

开发平台:

Visual C++

  1. /* ***** BEGIN LICENSE BLOCK *****
  2.  * Source last modified: $Id: hxpropwclnt.cpp,v 1.6.18.2 2004/07/09 02:07:27 hubbe Exp $
  3.  * 
  4.  * Portions Copyright (c) 1995-2004 RealNetworks, Inc. All Rights Reserved.
  5.  * 
  6.  * The contents of this file, and the files included with this file,
  7.  * are subject to the current version of the RealNetworks Public
  8.  * Source License (the "RPSL") available at
  9.  * http://www.helixcommunity.org/content/rpsl unless you have licensed
  10.  * the file under the current version of the RealNetworks Community
  11.  * Source License (the "RCSL") available at
  12.  * http://www.helixcommunity.org/content/rcsl, in which case the RCSL
  13.  * will apply. You may also obtain the license terms directly from
  14.  * RealNetworks.  You may not use this file except in compliance with
  15.  * the RPSL or, if you have a valid RCSL with RealNetworks applicable
  16.  * to this file, the RCSL.  Please see the applicable RPSL or RCSL for
  17.  * the rights, obligations and limitations governing use of the
  18.  * contents of the file.
  19.  * 
  20.  * Alternatively, the contents of this file may be used under the
  21.  * terms of the GNU General Public License Version 2 or later (the
  22.  * "GPL") in which case the provisions of the GPL are applicable
  23.  * instead of those above. If you wish to allow use of your version of
  24.  * this file only under the terms of the GPL, and not to allow others
  25.  * to use your version of this file under the terms of either the RPSL
  26.  * or RCSL, indicate your decision by deleting the provisions above
  27.  * and replace them with the notice and other provisions required by
  28.  * the GPL. If you do not delete the provisions above, a recipient may
  29.  * use your version of this file under the terms of any one of the
  30.  * RPSL, the RCSL or the GPL.
  31.  * 
  32.  * This file is part of the Helix DNA Technology. RealNetworks is the
  33.  * developer of the Original Code and owns the copyrights in the
  34.  * portions it created.
  35.  * 
  36.  * This file, and the files included with this file, is distributed
  37.  * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY
  38.  * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS
  39.  * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES
  40.  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET
  41.  * ENJOYMENT OR NON-INFRINGEMENT.
  42.  * 
  43.  * Technology Compatibility Kit Test Suite(s) Location:
  44.  *    http://www.helixcommunity.org/content/tck
  45.  * 
  46.  * Contributor(s):
  47.  * 
  48.  * ***** END LICENSE BLOCK ***** */
  49. #include "hlxclib/stdio.h"
  50. #include "hlxclib/string.h"
  51. #include "debug.h"
  52. #include "hxtypes.h"
  53. #include "hxcom.h"
  54. #include "hxcomm.h"
  55. #include "db_misc.h"
  56. #include "watchlst.h"
  57. #include "property.h"
  58. #include "commreg.h"
  59. #include "hxmon.h"
  60. #include "watchlst.h"
  61. #include "hxclreg.h"
  62. #include "hxpropwclnt.h"
  63. #include "hxslist.h"
  64. #include "hxheap.h"
  65. #ifdef _DEBUG
  66. #undef HX_THIS_FILE
  67. static const char HX_THIS_FILE[] = __FILE__;
  68. #endif
  69. /////////////////////////////////////////////////////////////////////////
  70. //  Method:
  71. //      HXClientPropWatch::QueryInterface
  72. //  Purpose:
  73. //      Implement this to export the interfaces supported by your
  74. //      object.
  75. //
  76. STDMETHODIMP
  77. HXClientPropWatch::QueryInterface(REFIID riid, void** ppvObj)
  78. {
  79.     QInterfaceList qiList[] =
  80.         {
  81.             { GET_IIDHANDLE(IID_IHXPropWatch), (IHXPropWatch*)this },
  82.             { GET_IIDHANDLE(IID_IUnknown), (IUnknown*)(IHXPropWatch*)this },
  83.         };
  84.     
  85.     return ::QIFind(qiList, QILISTSIZE(qiList), riid, ppvObj);
  86. }   
  87. /////////////////////////////////////////////////////////////////////////
  88. //  Method:
  89. //      HXClientPropWatch::AddRef
  90. //  Purpose:
  91. //      Everyone usually implements this the same... feel free to use
  92. //      this implementation.
  93. //
  94. STDMETHODIMP_(ULONG32)
  95. HXClientPropWatch::AddRef()
  96. {
  97.     return InterlockedIncrement(&m_lRefCount);
  98. }   
  99. /////////////////////////////////////////////////////////////////////////
  100. //  Method:
  101. //      HXClientPropWatch::Release
  102. //  Purpose:
  103. //      Everyone usually implements this the same... feel free to use
  104. //      this implementation.
  105. //
  106. STDMETHODIMP_(ULONG32)
  107. HXClientPropWatch::Release()
  108. {
  109.     if (InterlockedDecrement(&m_lRefCount) > 0)
  110.     {
  111.         return m_lRefCount;
  112.     }
  113.     
  114.     delete this;
  115.     return 0;
  116. }   
  117. HXClientPropWatch::HXClientPropWatch(CommonRegistry* pRegistry, IUnknown* pContext)
  118.    : m_lRefCount(0)
  119.    , m_pResponse(NULL)
  120.    , m_pRegistry(NULL)
  121.    , m_pInterruptSafeResponse(NULL)
  122.    , m_pInterruptState(NULL)
  123.    , m_pScheduler(NULL)
  124.    , m_pInternalResponse(NULL)
  125.    , m_pCallback(NULL)
  126. {
  127.     m_pRegistry = pRegistry;
  128.     /* 
  129.      * Users of HXClientRegistry should call Init and the context should
  130.      * expose IHXInterruptState and IHXScheduler if they want to
  131.      * ensure that watches are fired ONLY at non-interrupt time.
  132.      *
  133.      * Currently, this functionality is ONLY used by the client core
  134.      * since it is multi-threaded and needs to deal with
  135.      * top level clients which are not thread-safe.
  136.      */
  137.     if (pContext)
  138.     {
  139.      pContext->QueryInterface(IID_IHXScheduler, 
  140. (void**) &m_pScheduler);
  141. pContext->QueryInterface(IID_IHXInterruptState, 
  142. (void**) &m_pInterruptState);
  143.     }
  144.     m_pInternalResponse = new PropWatchResponse(this);
  145.     m_pInternalResponse->AddRef();
  146. }
  147. HXClientPropWatch::~HXClientPropWatch()
  148. {
  149.     if (m_pCallback &&
  150. m_pCallback->m_bIsCallbackPending &&
  151. m_pScheduler)
  152.     {
  153. m_pCallback->m_bIsCallbackPending = FALSE;
  154. m_pScheduler->Remove(m_pCallback->m_PendingHandle);
  155.     }
  156.     HX_RELEASE(m_pResponse);
  157.     HX_RELEASE(m_pInterruptSafeResponse);
  158.     HX_RELEASE(m_pInterruptState);
  159.     HX_RELEASE(m_pScheduler);
  160.     HX_RELEASE(m_pInternalResponse);
  161.     HX_RELEASE(m_pCallback);
  162. }
  163. /*
  164.  *  Function Name:   HXClientPropWatch::Init
  165.  *  Input Params:    IHXPropWatchResponse* pResponse, 
  166.  *  Return Value:    STDMETHODIMP
  167.  *  Description:
  168.  *      Initialize with the response object and the registry so that
  169.  *  Watch notifications can be sent back to the respective plugins.
  170.  */
  171. STDMETHODIMP
  172. HXClientPropWatch::Init(IHXPropWatchResponse* pResponse)
  173. {
  174.     if (pResponse)
  175.     {
  176. m_pResponse = pResponse;
  177. m_pResponse->AddRef();
  178. m_pResponse->QueryInterface(IID_IHXInterruptSafe, 
  179. (void**)&m_pInterruptSafeResponse);
  180. return HXR_OK;
  181.     }
  182.     return HXR_FAIL;
  183. }
  184. /*
  185.  *  Function Name:   SetWatchOnRoot
  186.  *  Input Params:
  187.  *  Return Value:    UINT32
  188.  *  Description:
  189.  *   set a watch point at the root of the registry hierarchy.
  190.  *  to be notified if any property at this level gets added/modified/deleted.
  191.  */
  192. STDMETHODIMP_(UINT32)
  193. HXClientPropWatch::SetWatchOnRoot()
  194. {
  195.     PropWatch* pPropWatch = new PropWatch;
  196.     pPropWatch->m_pResponse = m_pInternalResponse;
  197.     
  198.     return m_pRegistry->SetWatch(pPropWatch);
  199. }
  200. /*
  201.  *  Function Name:   SetWatchByName
  202.  *  Input Params:    const char* prop_name
  203.  *  Return Value:    UINT32
  204.  *  Description:
  205.  *   set a watch point on any Property. if the Property gets
  206.  *  modified/deleted a notification will be sent by the registry.
  207.  */
  208. STDMETHODIMP_(UINT32)
  209. HXClientPropWatch::SetWatchByName(const char* prop_name)
  210. {
  211.     UINT32 uiret = 0;
  212.     PropWatch* pPropWatch = new PropWatch;
  213.     pPropWatch->m_pResponse = m_pInternalResponse;
  214.     
  215.     uiret = m_pRegistry->SetWatch(prop_name, pPropWatch);
  216.     if ( uiret == 0 )
  217.     {
  218.         //Failed to add watch.
  219.         HX_DELETE( pPropWatch );
  220.     }
  221.     return uiret;
  222. }
  223. /*
  224.  *  Function Name:   SetWatchById
  225.  *  Input Params:    const UINT32 id
  226.  *  Return Value:    UINT32
  227.  *  Description:
  228.  *   set a watch point on any Property. if the Property gets
  229.  *  modified/deleted a notification will be sent by the registry.
  230.  */
  231. STDMETHODIMP_(UINT32)
  232. HXClientPropWatch::SetWatchById(const UINT32 id)
  233. {
  234.     UINT32 uiret = 0;
  235.     PropWatch* pPropWatch = new PropWatch;
  236.     pPropWatch->m_pResponse = m_pInternalResponse;
  237.     uiret = m_pRegistry->SetWatch(id, pPropWatch);
  238.     if ( uiret == 0 )
  239.     {
  240.         //Failed to add watch.
  241.         HX_DELETE( pPropWatch );
  242.     }
  243.     return uiret;
  244. }
  245. /*
  246.  *  Function Name:   ClearWatchOnRoot
  247.  *  Input Params:
  248.  *  Return Value:    HX_RESULT
  249.  *  Description:
  250.  *   clear a watch point from the root of the DB hierarchy
  251.  */
  252. STDMETHODIMP
  253. HXClientPropWatch::ClearWatchOnRoot()
  254. {
  255.     return m_pRegistry->ClearWatch(m_pInternalResponse);
  256. }
  257. /*
  258.  *  Function Name:   ClearWatchByName
  259.  *  Input Params:    const char* prop_name
  260.  *  Return Value:    HX_RESULT
  261.  *  Description:
  262.  *   clear a watch point on a property.
  263.  */
  264. STDMETHODIMP
  265. HXClientPropWatch::ClearWatchByName(const char* prop_name)
  266. {
  267.     return m_pRegistry->ClearWatch(prop_name, m_pInternalResponse);
  268. }
  269. /*
  270.  *  Function Name:   ClearWatchById
  271.  *  Input Params:    const UINT32 id
  272.  *  Return Value:    HX_RESULT
  273.  *  Description:
  274.  *   clear a watch point on a property.
  275.  */
  276. STDMETHODIMP
  277. HXClientPropWatch::ClearWatchById(const UINT32 id)
  278. {
  279.     return m_pRegistry->ClearWatch(id, m_pInternalResponse);
  280. }
  281. // PropWatchCallback
  282. HXClientPropWatch::PropWatchCallback::PropWatchCallback(HXClientPropWatch* pClientPropWatch) :
  283.      m_lRefCount (0)
  284.     ,m_PendingHandle (0)
  285.     ,m_pPropWatch(pClientPropWatch)
  286.     ,m_bIsCallbackPending (FALSE)
  287. {
  288. }
  289. HXClientPropWatch::PropWatchCallback::~PropWatchCallback()
  290. {
  291. }
  292. /*
  293.  * IUnknown methods
  294.  */
  295. /////////////////////////////////////////////////////////////////////////
  296. //      Method:
  297. //              IUnknown::QueryInterface
  298. //      Purpose:
  299. //              Implement this to export the interfaces supported by your
  300. //              object.
  301. //
  302. STDMETHODIMP HXClientPropWatch::PropWatchCallback::QueryInterface(REFIID riid, void** ppvObj)
  303. {
  304.     QInterfaceList qiList[] =
  305.         {
  306.             { GET_IIDHANDLE(IID_IHXCallback), (IHXCallback*)this },
  307.             { GET_IIDHANDLE(IID_IUnknown), (IUnknown*)(IHXCallback*)this },
  308.         };
  309.     
  310.     return ::QIFind(qiList, QILISTSIZE(qiList), riid, ppvObj);
  311. }
  312. /////////////////////////////////////////////////////////////////////////
  313. //      Method:
  314. //              IUnknown::AddRef
  315. //      Purpose:
  316. //              Everyone usually implements this the same... feel free to use
  317. //              this implementation.
  318. //
  319. STDMETHODIMP_(ULONG32) HXClientPropWatch::PropWatchCallback::AddRef()
  320. {
  321.     return InterlockedIncrement(&m_lRefCount);
  322. }
  323. /////////////////////////////////////////////////////////////////////////
  324. //      Method:
  325. //              IUnknown::Release
  326. //      Purpose:
  327. //              Everyone usually implements this the same... feel free to use
  328. //              this implementation.
  329. //
  330. STDMETHODIMP_(ULONG32) HXClientPropWatch::PropWatchCallback::Release()
  331. {
  332.     if (InterlockedDecrement(&m_lRefCount) > 0)
  333.     {
  334. return m_lRefCount;
  335.     }
  336.     delete this;
  337.     return 0;
  338. }
  339. /*
  340.  *      IHXCallback methods
  341.  */
  342. STDMETHODIMP HXClientPropWatch::PropWatchCallback::Func(void)
  343. {
  344.     m_PendingHandle         = 0;
  345.     m_bIsCallbackPending    = FALSE;
  346.     if (m_pPropWatch && m_pPropWatch->m_pInternalResponse)
  347.     {
  348. m_pPropWatch->m_pInternalResponse->ProcessPendingResponses();
  349. m_pPropWatch->Release();
  350.     }
  351.     return HXR_OK;
  352. }
  353. // PropWatchResponse
  354. HXClientPropWatch::PropWatchResponse::PropWatchResponse(HXClientPropWatch* pClientPropWatch) :
  355.      m_lRefCount (0)
  356.     ,m_pPropWatch(pClientPropWatch)
  357.     ,m_pPendingResponseList (NULL)
  358. {
  359. #ifdef THREADS_SUPPORTED
  360.     HXMutex::MakeMutex(m_pMutex);
  361. #else
  362.     HXMutex::MakeStubMutex(m_pMutex);
  363. #endif
  364. }
  365. HXClientPropWatch::PropWatchResponse::~PropWatchResponse()
  366. {
  367.     m_pMutex->Lock();
  368.     
  369.     while (m_pPendingResponseList && m_pPendingResponseList->GetCount() > 0)
  370.     {
  371. PropResponseValues* pValues = (PropResponseValues*) 
  372. m_pPendingResponseList->RemoveHead();
  373. delete pValues;
  374.     }
  375.     HX_DELETE(m_pPendingResponseList);
  376.     
  377.     m_pMutex->Unlock();
  378.     
  379.     HX_DELETE(m_pMutex);
  380. }
  381. /*
  382.  * IUnknown methods
  383.  */
  384. /////////////////////////////////////////////////////////////////////////
  385. //      Method:
  386. //              IUnknown::QueryInterface
  387. //      Purpose:
  388. //              Implement this to export the interfaces supported by your
  389. //              object.
  390. //
  391. STDMETHODIMP HXClientPropWatch::PropWatchResponse::QueryInterface(REFIID riid, void** ppvObj)
  392. {
  393.     QInterfaceList qiList[] =
  394.         {
  395.             { GET_IIDHANDLE(IID_IHXPropWatchResponse), (IHXPropWatchResponse*)this },
  396.             { GET_IIDHANDLE(IID_IUnknown), (IUnknown*)(IHXPropWatchResponse*)this },
  397.         };
  398.     
  399.     return ::QIFind(qiList, QILISTSIZE(qiList), riid, ppvObj);
  400. }
  401. /////////////////////////////////////////////////////////////////////////
  402. //      Method:
  403. //              IUnknown::AddRef
  404. //      Purpose:
  405. //              Everyone usually implements this the same... feel free to use
  406. //              this implementation.
  407. //
  408. STDMETHODIMP_(ULONG32) HXClientPropWatch::PropWatchResponse::AddRef()
  409. {
  410.     return InterlockedIncrement(&m_lRefCount);
  411. }
  412. /////////////////////////////////////////////////////////////////////////
  413. //      Method:
  414. //              IUnknown::Release
  415. //      Purpose:
  416. //              Everyone usually implements this the same... feel free to use
  417. //              this implementation.
  418. //
  419. STDMETHODIMP_(ULONG32) HXClientPropWatch::PropWatchResponse::Release()
  420. {
  421.     if (InterlockedDecrement(&m_lRefCount) > 0)
  422.     {
  423. return m_lRefCount;
  424.     }
  425.     delete this;
  426.     return 0;
  427. }
  428. /*
  429.  * IHXPropWatchResponse methods
  430.  */
  431. STDMETHODIMP
  432. HXClientPropWatch::PropWatchResponse::AddedProp(const UINT32 id,
  433.      const HXPropType    propType,
  434.      const UINT32 ulParentID)
  435. {
  436.     /* If we are at interrupt time, make sure that the 
  437.      * response is interrupt safe
  438.      */
  439.     if (m_pPropWatch->m_pInterruptState &&
  440. m_pPropWatch->m_pInterruptState->AtInterruptTime() &&
  441. (!m_pPropWatch->m_pInterruptSafeResponse ||
  442. !m_pPropWatch->m_pInterruptSafeResponse->IsInterruptSafe()))
  443.     {
  444. ScheduleCallback(ADDEDPROP, id, propType, ulParentID);
  445.     }
  446.     else
  447.     {
  448. ProcessPendingResponses();
  449. m_pPropWatch->m_pResponse->AddedProp(id, propType, ulParentID);
  450.     }
  451.     return HXR_OK;
  452. }
  453. STDMETHODIMP
  454. HXClientPropWatch::PropWatchResponse::ModifiedProp(const UINT32 id,
  455.      const HXPropType    propType,
  456.      const UINT32 ulParentID)
  457. {
  458.     /* If we are at interrupt time, make sure that the 
  459.      * response is interrupt safe
  460.      */
  461.     if (m_pPropWatch->m_pInterruptState &&
  462. m_pPropWatch->m_pInterruptState->AtInterruptTime() &&
  463. (!m_pPropWatch->m_pInterruptSafeResponse ||
  464. !m_pPropWatch->m_pInterruptSafeResponse->IsInterruptSafe()))
  465.     {
  466. ScheduleCallback(MODIFIEDPROP, id, propType, ulParentID);
  467.     }
  468.     else
  469.     {
  470. ProcessPendingResponses();
  471. m_pPropWatch->m_pResponse->ModifiedProp(id, propType, ulParentID);
  472.     }
  473.     return HXR_OK;
  474. }
  475. STDMETHODIMP
  476. HXClientPropWatch::PropWatchResponse::DeletedProp(const UINT32 id,
  477.      const UINT32 ulParentID)
  478. {
  479.     /* If we are at interrupt time, make sure that the 
  480.      * response is interrupt safe
  481.      */
  482.     if (m_pPropWatch->m_pInterruptState &&
  483. m_pPropWatch->m_pInterruptState->AtInterruptTime() &&
  484. (!m_pPropWatch->m_pInterruptSafeResponse ||
  485. !m_pPropWatch->m_pInterruptSafeResponse->IsInterruptSafe()))
  486.     {
  487. ScheduleCallback(DELETEDPROP, id, (HXPropType) 0, ulParentID);
  488.     }
  489.     else
  490.     {
  491. ProcessPendingResponses();
  492. m_pPropWatch->m_pResponse->DeletedProp(id, ulParentID);
  493.     }
  494.     return HXR_OK;
  495. }
  496. void
  497. HXClientPropWatch::PropWatchResponse::ScheduleCallback(ResponseType uResponseType,
  498.     const UINT32 id,
  499.     const HXPropType    propType,
  500.     const UINT32 ulParentID)
  501. {
  502.     m_pMutex->Lock();
  503.     
  504.     if (!m_pPendingResponseList)
  505.     {
  506. m_pPendingResponseList = new CHXSimpleList;
  507.     }
  508.     PropResponseValues* pValues = new PropResponseValues(uResponseType, id, 
  509.     propType, ulParentID);
  510.     m_pPendingResponseList->AddTail((void*) pValues);
  511.     if (!m_pPropWatch->m_pCallback)
  512.     {
  513. m_pPropWatch->m_pCallback = new PropWatchCallback(m_pPropWatch);
  514. m_pPropWatch->m_pCallback->AddRef();
  515.     }
  516.     if (!m_pPropWatch->m_pCallback->m_bIsCallbackPending &&
  517. m_pPropWatch->m_pScheduler)
  518.     {
  519. m_pPropWatch->AddRef();
  520. m_pPropWatch->m_pCallback->m_bIsCallbackPending = TRUE;
  521. m_pPropWatch->m_pCallback->m_PendingHandle = 
  522.     m_pPropWatch->m_pScheduler->RelativeEnter(
  523.     m_pPropWatch->m_pCallback, 0);
  524.     }
  525.     
  526.     m_pMutex->Unlock();
  527. }
  528. void
  529. HXClientPropWatch::PropWatchResponse::ProcessPendingResponses()
  530. {
  531.     /* remove any pending callback */
  532.     if (m_pPropWatch->m_pCallback &&
  533. m_pPropWatch->m_pCallback->m_bIsCallbackPending &&
  534. m_pPropWatch->m_pScheduler)
  535.     {
  536. m_pPropWatch->m_pCallback->m_bIsCallbackPending = FALSE;
  537. m_pPropWatch->m_pScheduler->Remove(
  538. m_pPropWatch->m_pCallback->m_PendingHandle);
  539.     }
  540.     m_pMutex->Lock();
  541.     
  542.     while (m_pPendingResponseList && m_pPendingResponseList->GetCount() > 0)
  543.     {
  544. PropResponseValues* pValues = (PropResponseValues*) 
  545. m_pPendingResponseList->RemoveHead();
  546. switch (pValues->m_uResponseType)
  547. {
  548.     case ADDEDPROP:
  549. m_pPropWatch->m_pResponse->AddedProp(pValues->m_ulId, 
  550.      pValues->m_propType,
  551.      pValues->m_ulParentID);
  552.      break;
  553.     case MODIFIEDPROP:
  554. m_pPropWatch->m_pResponse->ModifiedProp(pValues->m_ulId, 
  555.       pValues->m_propType,
  556.       pValues->m_ulParentID);
  557. break;
  558.     case DELETEDPROP:
  559. m_pPropWatch->m_pResponse->DeletedProp(pValues->m_ulId, 
  560.        pValues->m_ulParentID);
  561. break;
  562.     default:
  563. HX_ASSERT(0);
  564. break;
  565. }
  566. delete pValues;
  567.     }
  568.     
  569.     m_pMutex->Unlock();
  570. }