source: pacpusframework/branches/2.0-beta1/src/PacpusTools/src/Win32ShMem.cpp@ 162

Last change on this file since 162 was 162, checked in by Marek Kurdej, 11 years ago

Update: merged changes from trunk.

  • Property svn:executable set to *
File size: 5.4 KB
Line 
1// %pacpus:license{
2// This file is part of the PACPUS framework distributed under the
3// CECILL-C License, Version 1.0.
4/// @author Gerald Dherbomez <firstname.surname@utc.fr>
5/// @date January, 2007
6// %pacpus:license}
7
8#include <Pacpus/PacpusTools/Win32ShMem.h>
9#include <Pacpus/kernel/Log.h>
10
11#include <sstream>
12#include <windows.h>
13
14DECLARE_STATIC_LOGGER("pacpus.core.Win32ShMem");
15
16using namespace pacpus;
17using namespace std;
18
19//////////////////////////////////////////////////////////////////////////
20/// Constructor
21Win32ShMem::Win32ShMem(const char * name, int size)
22{
23 // semaphore name
24 stringstream semaphoreNameSs;
25 semaphoreNameSs << (const char *) "SemShMem_" << name;
26 string semaphoreName = semaphoreNameSs.str();
27 // event name
28 stringstream eventNameSs;
29 eventNameSs << (const char *) "EvtShMem_" << name;
30 string eventName = eventNameSs.str();
31
32 LOG_DEBUG("semaphore name = " << semaphoreName);
33 LOG_DEBUG("event name = " << eventName);
34
35 semaphore_ = CreateSemaphore(NULL, /* lInitialCount = */ 1, /* lMaximumCount = */ 1, semaphoreName.c_str());
36 if (semaphore_ == NULL) {
37 LPVOID lpMsgBuf;
38 DWORD dw = GetLastError();
39
40 FormatMessage(
41 /* flags = */ FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
42 /* source = */ NULL,
43 /* messageId = */ dw,
44 /* languageId = */ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
45 /* out buffer = */ (LPTSTR) &lpMsgBuf,
46 /* size = */ 0,
47 /* args = */ NULL
48 );
49
50 LOG_FATAL("cannot create semaphore protection of shared memory segment '" << name << "'"
51 << ". Error: " << GetLastError()
52 << ". Message: " << (const char *) lpMsgBuf
53 << ". Program will exit"
54 );
55 ::exit(-1);
56 }
57
58 // create the event - autoreset mode
59 event_ = CreateEvent(NULL, false, false, eventName.c_str());
60
61 // lock the semaphore and try to create the shared memory
62 lockMemory();
63 shMemHandle_ = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, size, name);
64 if (shMemHandle_ == NULL) {
65 LOG_FATAL("cannot create shared memory segment '" << name << "'"
66 << ". Error: " << GetLastError()
67 << ". Program will exit"
68 );
69 ::exit(-1);
70 }
71
72 // Map the memory to a local pointer
73 shMem_ = MapViewOfFile(shMemHandle_, FILE_MAP_ALL_ACCESS, 0, 0, 0);
74 if (shMem_ == NULL) {
75 LOG_FATAL("cannot map the view of file of the shared memory segment '" << name << "'"
76 << ". Error: " << GetLastError()
77 << ". Program will exit"
78 );
79 ::exit(-1);
80 }
81
82 LOG_INFO("created Win32 shared memory '" << name << "'");
83
84 unlockMemory();
85}
86
87//////////////////////////////////////////////////////////////////////////
88/// Destructor
89Win32ShMem::~Win32ShMem()
90{
91 // free the semaphore
92 CloseHandle(semaphore_);
93 UnmapViewOfFile(shMem_);
94 CloseHandle(shMemHandle_);
95}
96
97//////////////////////////////////////////////////////////////////////////
98/// Use this method to wait the incoming of new data
99/// you can specify a timeout in ms to avoid infinite blocking or 0 (infinite)
100/// @returns @b true if new data available before the timeout, @b false otherwise
101bool Win32ShMem::wait(unsigned long timeout /* = 0 */)
102{
103 if (timeout == 0) {
104 timeout = INFINITE;
105 }
106
107 DWORD status = 0;
108 status = WaitForSingleObject(event_, timeout);
109
110 if (status == WAIT_OBJECT_0) {
111 return true;
112 } else {
113 return false;
114 }
115}
116
117//////////////////////////////////////////////////////////////////////////
118/// Use this method to get a pointer to data of the shared memory
119void * Win32ShMem::read()
120{
121 void * shMem;
122 lockMemory();
123 shMem = shMem_;
124 unlockMemory();
125 return shMem;
126}
127
128//////////////////////////////////////////////////////////////////////////
129/// Use this method to get a pointer to data of the shared memory
130void Win32ShMem::read(void * mem, int size)
131{
132 lockMemory();
133 memcpy(mem,shMem_,size);
134 unlockMemory();
135}
136
137//////////////////////////////////////////////////////////////////////////
138/// Return the event handle under Windows
139void * Win32ShMem::getEventIdentifier()
140{
141 return event_;
142}
143
144//////////////////////////////////////////////////////////////////////////
145/// Use this method to write data in shared memory. Offset is given in bytes
146void Win32ShMem::write(void *data, int size, unsigned long offset)
147{
148 lockMemory();
149 //unsigned long * dest = (unsigned long *)shMem_ + offset;
150 char * dest = (char *)shMem_ + offset;
151 //printf("adresses : shm : %x dest : %x offset : %x \n",shMem_, dest, offset);
152 memcpy(dest, data, size);
153 unlockMemory();
154 SetEvent(event_);
155}
156
157//////////////////////////////////////////////////////////////////////////
158/// Function that locks access to the shared memory
159void Win32ShMem::lockMemory()
160{
161 WaitForSingleObject(semaphore_, INFINITE);
162}
163
164//////////////////////////////////////////////////////////////////////////
165/// Function that unlocks access to the shared memory
166void Win32ShMem::unlockMemory()
167{
168 ReleaseSemaphore(semaphore_, 1, NULL);
169}
Note: See TracBrowser for help on using the repository browser.