Skip to content

Commit 1f8ee7c

Browse files
Fix: undefined behavior in destructor, cross-platform guards, and infinite loop issues (Issue #236)
1 parent f791ab0 commit 1f8ee7c

1 file changed

Lines changed: 60 additions & 17 deletions

File tree

concore.hpp

Lines changed: 60 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,11 @@
1212
//libraries for platform independent delay. Supports C++11 upwards
1313
#include <chrono>
1414
#include <thread>
15+
#ifdef __linux__
1516
#include <sys/ipc.h>
1617
#include <sys/shm.h>
1718
#include <unistd.h>
19+
#endif
1820
#include <cstring>
1921
#include <cctype>
2022

@@ -32,11 +34,11 @@ class Concore{
3234
string inpath = "./in";
3335
string outpath = "./out";
3436

35-
int shmId_create;
36-
int shmId_get;
37+
int shmId_create = -1;
38+
int shmId_get = -1;
3739

38-
char* sharedData_create;
39-
char* sharedData_get;
40+
char* sharedData_create = nullptr;
41+
char* sharedData_get = nullptr;
4042
// File sharing:- 0, Shared Memory:- 1
4143
int communication_iport = 0; // iport refers to input port
4244
int communication_oport = 0; // oport refers to input port
@@ -56,14 +58,23 @@ class Concore{
5658
Concore(){
5759
iport = mapParser("concore.iport");
5860
oport = mapParser("concore.oport");
59-
std::map<std::string, int>::iterator it_iport = iport.begin();
60-
std::map<std::string, int>::iterator it_oport = oport.begin();
61-
int iport_number = ExtractNumeric(it_iport->first);
62-
int oport_number = ExtractNumeric(it_oport->first);
61+
62+
int iport_number = -1;
63+
int oport_number = -1;
64+
65+
if (!iport.empty()) {
66+
std::map<std::string, int>::iterator it_iport = iport.begin();
67+
iport_number = ExtractNumeric(it_iport->first);
68+
}
69+
if (!oport.empty()) {
70+
std::map<std::string, int>::iterator it_oport = oport.begin();
71+
oport_number = ExtractNumeric(it_oport->first);
72+
}
6373

6474
// if iport_number and oport_number is equal to -1 then it refers to File Method,
6575
// otherwise it refers to Shared Memory and the number represent the unique key.
6676

77+
#ifdef __linux__
6778
if(oport_number != -1)
6879
{
6980
// oport_number is not equal to -1 so refers to SM and value is key.
@@ -76,7 +87,8 @@ class Concore{
7687
// iport_number is not equal to -1 so refers to SM and value is key.
7788
communication_iport = 1;
7889
this->getSharedMemory(iport_number);
79-
}
90+
}
91+
#endif
8092
}
8193

8294
/**
@@ -85,12 +97,20 @@ class Concore{
8597
*/
8698
~Concore()
8799
{
100+
#ifdef __linux__
88101
// Detach the shared memory segment from the process
89-
shmdt(sharedData_create);
90-
shmdt(sharedData_get);
102+
if (communication_oport == 1 && sharedData_create != nullptr) {
103+
shmdt(sharedData_create);
104+
}
105+
if (communication_iport == 1 && sharedData_get != nullptr) {
106+
shmdt(sharedData_get);
107+
}
91108

92109
// Remove the shared memory segment
93-
shmctl(shmId_create, IPC_RMID, nullptr);
110+
if (shmId_create != -1) {
111+
shmctl(shmId_create, IPC_RMID, nullptr);
112+
}
113+
#endif
94114
}
95115

96116
/**
@@ -127,6 +147,7 @@ class Concore{
127147
return std::stoi(numberString);
128148
}
129149

150+
#ifdef __linux__
130151
/**
131152
* @brief Creates a shared memory segment with the given key.
132153
* @param key The key for the shared memory segment.
@@ -143,6 +164,7 @@ class Concore{
143164
sharedData_create = static_cast<char*>(shmat(shmId_create, NULL, 0));
144165
if (sharedData_create == reinterpret_cast<char*>(-1)) {
145166
std::cerr << "Failed to attach shared memory segment." << std::endl;
167+
sharedData_create = nullptr;
146168
}
147169
}
148170

@@ -153,7 +175,9 @@ class Concore{
153175
*/
154176
void getSharedMemory(key_t key)
155177
{
156-
while (true) {
178+
int retry = 0;
179+
const int MAX_RETRY = 100;
180+
while (retry < MAX_RETRY) {
157181
// Get the shared memory segment created by Writer
158182
shmId_get = shmget(key, 256, 0666);
159183
// Check if shared memory exists
@@ -163,11 +187,22 @@ class Concore{
163187

164188
std::cout << "Shared memory does not exist. Make sure the writer process is running." << std::endl;
165189
sleep(1); // Sleep for 1 second before checking again
190+
retry++;
191+
}
192+
193+
if (shmId_get == -1) {
194+
std::cerr << "Failed to get shared memory segment after max retries." << std::endl;
195+
return;
166196
}
167197

168198
// Attach the shared memory segment to the process's address space
169199
sharedData_get = static_cast<char*>(shmat(shmId_get, NULL, 0));
200+
if (sharedData_get == reinterpret_cast<char*>(-1)) {
201+
std::cerr << "Failed to attach shared memory segment." << std::endl;
202+
sharedData_get = nullptr;
203+
}
170204
}
205+
#endif
171206

172207
/**
173208
* @brief Parses a file containing port and number mappings and returns a map of the values.
@@ -187,6 +222,10 @@ class Concore{
187222
portfile.close();
188223
}
189224

225+
if (portstr.empty()) {
226+
return ans;
227+
}
228+
190229
portstr[portstr.size()-1]=',';
191230
portstr+='}';
192231
int i=0;
@@ -303,7 +342,9 @@ class Concore{
303342
ins = initstr;
304343
}
305344

306-
while ((int)ins.length()==0){
345+
int retry = 0;
346+
const int MAX_RETRY = 100;
347+
while ((int)ins.length()==0 && retry < MAX_RETRY){
307348
this_thread::sleep_for(timespan);
308349
try{
309350
ifstream infile;
@@ -324,8 +365,7 @@ class Concore{
324365
catch(...){
325366
cout<<"Read error";
326367
}
327-
328-
368+
retry++;
329369
}
330370
s += ins;
331371

@@ -368,7 +408,9 @@ class Concore{
368408
ins = initstr;
369409
}
370410

371-
while ((int)ins.length()==0){
411+
int retry = 0;
412+
const int MAX_RETRY = 100;
413+
while ((int)ins.length()==0 && retry < MAX_RETRY){
372414
this_thread::sleep_for(timespan);
373415
try{
374416
if(shmId_get != -1) {
@@ -385,6 +427,7 @@ class Concore{
385427
catch(...){
386428
std::cout << "Read error" << std::endl;
387429
}
430+
retry++;
388431
}
389432
s += ins;
390433

0 commit comments

Comments
 (0)