shmhelp.cpp
上传用户:zhongxx05
上传日期:2007-06-06
资源大小:33641k
文件大小:6k
源码类别:

Symbian

开发平台:

C/C++

  1. /* ***** BEGIN LICENSE BLOCK ***** 
  2.  * Version: RCSL 1.0/RPSL 1.0 
  3.  *  
  4.  * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. 
  5.  *      
  6.  * The contents of this file, and the files included with this file, are 
  7.  * subject to the current version of the RealNetworks Public Source License 
  8.  * Version 1.0 (the "RPSL") available at 
  9.  * http://www.helixcommunity.org/content/rpsl unless you have licensed 
  10.  * the file under the RealNetworks Community Source License Version 1.0 
  11.  * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, 
  12.  * in which case the RCSL will apply. You may also obtain the license terms 
  13.  * directly from RealNetworks.  You may not use this file except in 
  14.  * compliance with the RPSL or, if you have a valid RCSL with RealNetworks 
  15.  * applicable to this file, the RCSL.  Please see the applicable RPSL or 
  16.  * RCSL for the rights, obligations and limitations governing use of the 
  17.  * contents of the file.  
  18.  *  
  19.  * This file is part of the Helix DNA Technology. RealNetworks is the 
  20.  * developer of the Original Code and owns the copyrights in the portions 
  21.  * it created. 
  22.  *  
  23.  * This file, and the files included with this file, is distributed and made 
  24.  * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
  25.  * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
  26.  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS 
  27.  * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
  28.  * 
  29.  * Technology Compatibility Kit Test Suite(s) Location: 
  30.  *    http://www.helixcommunity.org/content/tck 
  31.  * 
  32.  * Contributor(s): 
  33.  *  
  34.  * ***** END LICENSE BLOCK ***** */ 
  35. // for shared memory
  36. #include <sys/types.h>
  37. #include <sys/ipc.h>
  38. #include <sys/shm.h>
  39. #include <sys/utsname.h>
  40. #include "hlxclib/string.h"
  41. #include "shmhelp.h"
  42. #include "hxassert.h"
  43. //Work around AIX problem.
  44. #ifdef _AIX
  45. #  define MAX_SHARED_REGIONS ((UINT32)1)
  46. #else
  47. #  define MAX_SHARED_REGIONS ((UINT32)9999)
  48. #endif
  49. //Keeps track of how many shared memory segments we have used.
  50. int      ShmHelp::zm_nSegment = 0;
  51. Display* ShmHelp::zm_pDisplay = NULL;
  52. BOOL     ShmHelp::zm_bUseShm  = FALSE;
  53. void ShmHelp::Init(Display* pDisplay)
  54. {
  55.    HX_ASSERT( pDisplay );
  56.    zm_pDisplay = pDisplay;
  57.    zm_bUseShm  = FALSE;
  58.    
  59.    //See if our XServer supports ShmMemory....
  60. #if defined(_AIX)  
  61.    int majorVersion, minorVersion;
  62.    Bool sharedPixmaps;
  63.    // doesn't seem to work with multiple presentation panes...
  64.    zm_bUseShm = XShmQueryVersion( zm_pDisplay,
  65.                                   &majorVersion,
  66.                                   &minorVersion, &sharedPixmaps); 
  67.    if (zm_nSegment > AIX_MAX_SHARED_REGIONS) 
  68.       zm_bUseShm = FALSE;
  69. #else
  70. #  ifdef _SOLARIS
  71.    zm_bUseShm = FALSE;
  72. #  else    
  73.    zm_bUseShm = XShmQueryExtension(zm_pDisplay);
  74. #  endif    
  75. #endif    
  76.    //Make sure we only use it if we are displaying locally.  The
  77.    //DISPLAY string can start with ':', '0' or the machine name.
  78.    if(zm_bUseShm)
  79.    {
  80.       char *disp = getenv("DISPLAY");
  81.       HX_ASSERT( disp != NULL && "Your display variable isn't set!" );
  82.       if(!disp)
  83.       {
  84.          zm_bUseShm = FALSE;
  85.       }
  86.       else if( disp[0]!=':' && disp[0]!='0' )
  87.       {
  88.          //See if our machine name is in the dipsplay string.
  89.          struct utsname inf;
  90.          uname(&inf);
  91.          if( (strlen(disp)<=strlen(inf.machine)) ||
  92.              (strncmp(disp, inf.machine, strlen(inf.machine))) )
  93.          {
  94.             zm_bUseShm = FALSE;
  95.          }
  96.       }
  97.    }
  98. }
  99. //This ctor implies someone has called the one that sets the
  100. //display var.
  101. ShmHelp::ShmHelp()
  102. {
  103.    HX_ASSERT( zm_pDisplay );
  104. }
  105. BOOL ShmHelp::ShmAvailable()
  106. {
  107.    return zm_bUseShm;
  108. }
  109. HX_RESULT ShmHelp::CreateSharedRegion(INT32 nSize, UCHAR**ppMem, int* pnShmID, XShmSegmentInfo* pInfo ) 
  110. {
  111.     HX_RESULT theErr   = HXR_OK;
  112.     int       nRetCode = 0;
  113.     HX_ASSERT( ppMem );
  114.     HX_ASSERT( pnShmID );
  115.     //Make sure we were inited...
  116.     HX_ASSERT(zm_pDisplay);
  117.     if( !zm_pDisplay )
  118.        return HXR_UNEXPECTED;
  119.     *ppMem   = NULL;
  120.     *pnShmID = -1;
  121.     
  122.     //get the shared memory segment, etc.
  123.     if( !zm_bUseShm ) 
  124.     {
  125. theErr = HXR_UNEXPECTED;
  126.     }
  127.     
  128. #ifdef _AIX
  129.     if (zm_nSegment > AIX_MAX_SHARED_REGIONS)
  130.     {
  131. theErr = HXR_UNEXPECTED;
  132.     }
  133. #endif
  134.     if( theErr == HXR_OK )
  135.     {
  136.         // Request a new shared memory ID
  137.         *pnShmID = ::shmget(0, nSize, IPC_CREAT | 0777);
  138.     
  139.         if( *pnShmID == -1 ) 
  140.         {
  141. #ifdef _DEBUG
  142.             perror("shmget");
  143. #endif            
  144.             theErr = HXR_FAIL;
  145.         }
  146.         else
  147.         {
  148.             // Attach shared memory segment to process's address space
  149.             *ppMem = (UCHAR*)::shmat(*pnShmID, 0, 0);
  150.             if( ((int)*ppMem) == -1) 
  151.             {
  152.                 theErr = HXR_FAIL;
  153. #ifdef _DEBUG            
  154.                 perror("shmat");
  155. #endif            
  156.             }
  157.             else
  158.             {
  159.                 //Request that segment be removed after last reference to it 
  160.                 //is released
  161.                 pInfo->shmseg   = ++zm_nSegment;
  162.                 pInfo->shmid    = *pnShmID;
  163.                 pInfo->shmaddr  = (char*)*ppMem;
  164.                 pInfo->readOnly = True;
  165.                 nRetCode = XShmAttach(zm_pDisplay, pInfo);
  166.                 XSync(zm_pDisplay, False);
  167.                 ::shmctl(*pnShmID, IPC_RMID, NULL); 
  168.     
  169.                 if( !nRetCode )
  170.                 {
  171.                     theErr = HXR_FAIL;
  172.                 }
  173.                 else
  174.                 {
  175.                     theErr = HXR_OK;
  176.                 }
  177.             }
  178.         }
  179.         if( HXR_OK != theErr )
  180.         {
  181.             // in case of failure, make a best case effort to detach the region
  182.             ::shmctl(*pnShmID, IPC_RMID, NULL);
  183.             zm_bUseShm = FALSE;
  184.         }
  185.     }
  186.     return theErr;
  187. }
  188. HX_RESULT ShmHelp::DetachSharedRegion(UCHAR**ppMem, XShmSegmentInfo* pInfo ) 
  189. {
  190.    HX_ASSERT(zm_bUseShm);
  191.    HX_ASSERT(pInfo);
  192.    HX_ASSERT(*ppMem);
  193.    
  194.    //Make sure we were inited...
  195.    HX_ASSERT(zm_pDisplay);
  196.    if( !zm_pDisplay )
  197.       return HXR_UNEXPECTED;
  198.    
  199.    if(!zm_bUseShm)
  200.       return HXR_UNEXPECTED;
  201.    
  202.    XShmDetach(zm_pDisplay, pInfo);
  203.    
  204.    ::shmdt((char*)*ppMem);
  205.    *ppMem = NULL;
  206.    
  207.    --zm_nSegment;
  208.    
  209.    return HXR_OK;
  210. }