libsharememory.cpp 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380
  1. // libsharememory.cpp : 定义 DLL 应用程序的导出函数。
  2. //
  3. #ifdef _WIN32
  4. #include "stdafx.h"
  5. #include <windows.h>
  6. #else
  7. #include<string.h>
  8. #include<errno.h>
  9. #include <sys/mman.h>
  10. #include <unistd.h>
  11. #include <fcntl.h>
  12. #include <semaphore.h>
  13. #include <time.h>
  14. #include <sys/stat.h>
  15. #endif
  16. #include "libsharememory.h"
  17. class libsharememory_impl
  18. {
  19. protected:
  20. unsigned int m_dwBytes;
  21. bool m_bLocked;
  22. void* m_pData;
  23. #ifdef _WIN32
  24. HANDLE m_hFileMap;
  25. HANDLE m_hMutex;
  26. #else
  27. int m_shid;
  28. sem_t* m_semt;
  29. char m_strsemname[MAX_PATH];
  30. char m_strshmname[MAX_PATH];
  31. #endif // _WIN32
  32. public:
  33. libsharememory_impl()
  34. {
  35. #ifdef _WIN32
  36. m_hMutex = NULL;
  37. m_hFileMap = NULL;
  38. #else
  39. m_shid = -1;
  40. m_semt = SEM_FAILED;
  41. memset(m_strsemname, 0, MAX_PATH);
  42. memset(m_strshmname, 0, MAX_PATH);
  43. #endif // _WIN32
  44. m_dwBytes=0;
  45. m_pData=NULL;
  46. m_bLocked = false;
  47. }
  48. ~libsharememory_impl()
  49. {
  50. CloseShareMem();
  51. }
  52. //创建共享内存区
  53. bool CreateShareMem(const char* szName, unsigned int dwBytes)
  54. {
  55. bool bRet = false;
  56. #ifdef _WIN32
  57. char szBuf[MAX_PATH] = {0};
  58. const char* szFile;
  59. if (szName != NULL && dwBytes > 0)
  60. {
  61. CloseShareMem();
  62. szFile = tmpnam(szBuf);
  63. if (szFile != NULL)
  64. {
  65. m_hFileMap = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, dwBytes + sizeof(unsigned int) + sizeof(int), szName);
  66. if (m_hFileMap != NULL)
  67. {
  68. m_dwBytes = dwBytes;
  69. m_pData = MapViewOfFile(m_hFileMap, FILE_MAP_ALL_ACCESS, 0, 0, 0);
  70. if (m_pData != NULL)
  71. {
  72. *((LPDWORD)m_pData) = dwBytes;
  73. _snprintf(szBuf, MAX_PATH, "Mutex<%s>", szName);
  74. m_hMutex = CreateMutex(NULL, false, szBuf);
  75. if (m_hMutex != NULL)
  76. {
  77. if (GetLastError() != ERROR_ALREADY_EXISTS)
  78. {
  79. bRet = true;
  80. }
  81. }
  82. }
  83. }
  84. if (!bRet)
  85. {
  86. CloseShareMem();
  87. }
  88. }
  89. }
  90. #else
  91. if (szName != NULL && dwBytes > 0) {
  92. char szBuf[MAX_PATH] = { 0 };
  93. const char* szFile = tmpnam(szBuf);
  94. if (szFile != NULL) {
  95. snprintf(m_strshmname, MAX_PATH, "%s", szName);
  96. snprintf(m_strsemname, MAX_PATH, "/mutex.%s", szName);
  97. m_shid = shm_open(szName, O_CREAT | O_RDWR | O_EXCL, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
  98. if (m_shid >= 0) {
  99. //Debug("%s:%d shm_open O_CREAT|O_RDWR|O_EXCL success and share memory %s and size is %d", __FUNCTION__, __LINE__, szName, dwBytes);
  100. }
  101. else {
  102. //Debug("%s:%d shm_open O_CREAT|O_RDWR|O_EXCL %s failed for %s, and errno is %d", __FUNCTION__, __LINE__, m_strshmname, strerror(errno), errno);
  103. if (EEXIST == errno) {
  104. m_shid = shm_open(szName, O_RDWR, 0);
  105. }
  106. }
  107. if (m_shid >= 0) {
  108. if (NULL == m_pData) {
  109. ftruncate(m_shid, dwBytes);
  110. m_pData = mmap(NULL, dwBytes, PROT_READ | PROT_WRITE, MAP_SHARED, m_shid, 0);
  111. if (MAP_FAILED != m_pData) {
  112. *((unsigned int*)m_pData) = dwBytes;
  113. m_dwBytes = dwBytes;
  114. sem_t* semt = sem_open(m_strsemname, O_CREAT | O_EXCL, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH, 1);
  115. if (NULL == semt) {
  116. if (EEXIST == errno) {
  117. semt = sem_open(m_strsemname, 0);
  118. sem_init(semt, 32, 1);
  119. }
  120. }
  121. if (NULL != semt) {
  122. m_semt = semt;
  123. int ivalue = -1;
  124. sem_getvalue(m_semt, &ivalue);
  125. bRet = true;
  126. }
  127. }
  128. }
  129. }
  130. }
  131. }
  132. #endif // _WIN32
  133. return bRet;
  134. }
  135. //打开已有的共享内存区
  136. bool OpenShareMem(const char* szName)
  137. {
  138. bool bRet = false;
  139. #ifdef _WIN32
  140. char szBuf[MAX_PATH];
  141. if (szName != NULL)
  142. {
  143. CloseShareMem();
  144. m_hFileMap = OpenFileMapping(FILE_MAP_ALL_ACCESS, false, szName);
  145. if (m_hFileMap != NULL)
  146. {
  147. sprintf_s(szBuf, "Mutex<%s>", szName);
  148. m_hMutex = OpenMutex(MUTEX_ALL_ACCESS, false, szBuf);
  149. if (m_hMutex != NULL)
  150. {
  151. m_pData = MapViewOfFile(m_hFileMap, FILE_MAP_ALL_ACCESS, 0, 0, 0);
  152. if (LockShareMem())
  153. {
  154. m_dwBytes = *((LPDWORD)m_pData);
  155. //m_nEntityNum = *((int*)((LPDWORD)m_pData+1));
  156. //*((int*)((LPDWORD)m_pData+1)) = ++m_nEntityNum;
  157. UnlockShareMem();
  158. if (m_dwBytes > 0)
  159. {
  160. bRet = true;
  161. }
  162. }
  163. }
  164. }
  165. if (!bRet)
  166. {
  167. CloseShareMem();
  168. }
  169. }
  170. #else
  171. if (szName != NULL) {
  172. int shid = shm_open(szName, O_RDWR, 0);
  173. if (-1 != shid) {
  174. m_shid = shid;
  175. sem_t* semt = sem_open(m_strsemname, 0);
  176. if (SEM_FAILED != semt){
  177. m_semt = semt;
  178. int ivalue = -1;
  179. sem_getvalue(semt, &ivalue);
  180. m_pData = mmap(NULL, m_dwBytes, PROT_READ | PROT_WRITE, MAP_SHARED, shid, 0);
  181. if (MAP_FAILED != m_pData) {
  182. if (LockShareMem()){
  183. m_dwBytes = *((unsigned int*)m_pData);
  184. UnlockShareMem();
  185. if (m_dwBytes > 0){
  186. bRet = true;
  187. }
  188. }
  189. }
  190. }
  191. }
  192. if (!bRet){
  193. CloseShareMem();
  194. }
  195. }
  196. #endif // RVC_OS_WIN
  197. return bRet;
  198. }
  199. //释放共享内存区
  200. void CloseShareMem()
  201. {
  202. if (m_bLocked){
  203. UnlockShareMem();
  204. }
  205. #ifdef _WIN32
  206. if (m_pData != NULL){
  207. UnmapViewOfFile(m_pData);
  208. m_pData = NULL;
  209. }
  210. if (m_hFileMap != NULL){
  211. CloseHandle(m_hFileMap);
  212. m_hFileMap = NULL;
  213. }
  214. if (m_hMutex != NULL){
  215. CloseHandle(m_hMutex);
  216. m_hMutex = NULL;
  217. }
  218. #else
  219. if (SEM_FAILED != m_semt){
  220. sem_unlink(m_strsemname);
  221. m_semt = SEM_FAILED;
  222. }
  223. if (m_pData != NULL){
  224. munmap(m_pData, m_dwBytes);
  225. }
  226. if (m_shid >= 0) {
  227. shm_unlink(m_strshmname);
  228. close(m_shid);
  229. m_shid = -1;
  230. }
  231. #endif //_MSC_VER
  232. m_dwBytes = 0;
  233. }
  234. //获取共享内存区大小
  235. unsigned int GetShareMemBytes()
  236. {
  237. return m_dwBytes;
  238. }
  239. //是否有可用的内存区
  240. bool IsShareMemValid()
  241. {
  242. #ifdef _WIN32
  243. return (m_hFileMap != NULL && m_hMutex != NULL);
  244. #else
  245. return (m_shid != -1 && m_semt != NULL);
  246. #endif // _WIN32
  247. }
  248. //锁定访问内存区
  249. void* LockShareMem(unsigned int dwWaitTimeout=INFINITE)
  250. {
  251. void* pData=NULL;
  252. if (IsShareMemValid() && m_pData != NULL && !m_bLocked)
  253. {
  254. #ifdef _WIN32
  255. if (WaitForSingleObject(m_hMutex, dwWaitTimeout) != WAIT_TIMEOUT){
  256. m_bLocked = true;
  257. }
  258. if (m_bLocked){
  259. pData = (void*)((LPDWORD)m_pData + 1);
  260. }
  261. #else
  262. struct timespec ts;
  263. clock_gettime(CLOCK_REALTIME, &ts);
  264. long unsec = ts.tv_nsec + (1000*1000*dwWaitTimeout);
  265. ts.tv_sec += (unsec / 1000000000);
  266. ts.tv_nsec = (unsec % 1000000000);
  267. int ivalue = -1;
  268. sem_getvalue(m_semt, &ivalue);
  269. if (0 == sem_timedwait(m_semt,&ts)) {
  270. sem_getvalue(m_semt, &ivalue);
  271. m_bLocked = true;
  272. }
  273. #endif // _WIN32
  274. if (m_bLocked){
  275. pData = (void*)((unsigned int*)m_pData + 1);
  276. }
  277. }
  278. return pData;
  279. }
  280. //内存区是否互斥锁定
  281. bool IsShareMemLocked()
  282. {
  283. return m_bLocked;
  284. }
  285. //解锁内存区
  286. void UnlockShareMem()
  287. {
  288. if (m_bLocked)
  289. {
  290. #ifdef _WIN32
  291. ReleaseMutex(m_hMutex);
  292. #else
  293. sem_post(m_semt);
  294. #endif // _WIN32
  295. m_bLocked = false;
  296. }
  297. }
  298. };
  299. // 这是已导出类的构造函数。
  300. // 有关类定义的信息,请参阅 libsharememory.h
  301. Clibsharememory::Clibsharememory()
  302. {
  303. m_pImpl = new libsharememory_impl;
  304. return;
  305. }
  306. Clibsharememory::~Clibsharememory()
  307. {
  308. delete m_pImpl;
  309. }
  310. void Clibsharememory::Unlock()
  311. {
  312. m_pImpl->UnlockShareMem();
  313. return;
  314. }
  315. bool Clibsharememory::IsLocked()
  316. {
  317. bool bRst = m_pImpl->IsShareMemLocked();
  318. return bRst;
  319. }
  320. void* Clibsharememory::Lock(unsigned int dwWaitTimeout)
  321. {
  322. void* lpVoid = m_pImpl->LockShareMem(dwWaitTimeout);
  323. return lpVoid;
  324. }
  325. bool Clibsharememory::IsValid()
  326. {
  327. bool bRst = m_pImpl->IsShareMemValid();
  328. return bRst;
  329. }
  330. unsigned int Clibsharememory::GetBytes()
  331. {
  332. unsigned int TotalBytes = m_pImpl->GetShareMemBytes();
  333. return TotalBytes;
  334. }
  335. void Clibsharememory::Close()
  336. {
  337. m_pImpl->CloseShareMem();
  338. return;
  339. }
  340. bool Clibsharememory::Open(const char* szName)
  341. {
  342. return m_pImpl->OpenShareMem(szName);
  343. }
  344. bool Clibsharememory::Create(const char* szName, unsigned int dwBytes)
  345. {
  346. return m_pImpl->CreateShareMem(szName,dwBytes);
  347. }