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 |
|
---|
14 | DECLARE_STATIC_LOGGER("pacpus.core.Win32ShMem");
|
---|
15 |
|
---|
16 | using namespace pacpus;
|
---|
17 | using namespace std;
|
---|
18 |
|
---|
19 | //////////////////////////////////////////////////////////////////////////
|
---|
20 | /// Constructor
|
---|
21 | Win32ShMem::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
|
---|
89 | Win32ShMem::~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
|
---|
101 | bool 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
|
---|
119 | void * 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
|
---|
130 | void 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
|
---|
139 | void * Win32ShMem::getEventIdentifier()
|
---|
140 | {
|
---|
141 | return event_;
|
---|
142 | }
|
---|
143 |
|
---|
144 | //////////////////////////////////////////////////////////////////////////
|
---|
145 | /// Use this method to write data in shared memory. Offset is given in bytes
|
---|
146 | void 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
|
---|
159 | void Win32ShMem::lockMemory()
|
---|
160 | {
|
---|
161 | WaitForSingleObject(semaphore_, INFINITE);
|
---|
162 | }
|
---|
163 |
|
---|
164 | //////////////////////////////////////////////////////////////////////////
|
---|
165 | /// Function that unlocks access to the shared memory
|
---|
166 | void Win32ShMem::unlockMemory()
|
---|
167 | {
|
---|
168 | ReleaseSemaphore(semaphore_, 1, NULL);
|
---|
169 | }
|
---|