Skip to content

Commit 37bf693

Browse files
committed
Improvements on the SharedFiles class
examples/multiprocess_c/multi
1 parent 55d28af commit 37bf693

File tree

2 files changed

+177
-51
lines changed

2 files changed

+177
-51
lines changed

src/utils/shared_files.cc

+92-42
Original file line numberDiff line numberDiff line change
@@ -27,30 +27,33 @@
2727
#include <stdlib.h>
2828
#include <string.h>
2929

30-
30+
#include <utility>
3131
#include <fstream>
3232
#include <string>
3333

3434
namespace modsecurity {
3535
namespace utils {
3636

3737

38-
msc_file_handler_t *SharedFiles::find_handler(
38+
std::pair<msc_file_handler *, FILE *> SharedFiles::find_handler(
3939
const std::string &fileName) {
40-
for (const auto &i: m_handlers) {
40+
for (const auto &i : m_handlers) {
4141
if (i.first == fileName) {
4242
return i.second;
4343
}
4444
}
45-
return NULL;
45+
return std::pair<modsecurity::utils::msc_file_handler*,
46+
_IO_FILE*>(NULL, NULL);
4647
}
4748

4849

49-
msc_file_handler_t *SharedFiles::add_new_handler(
50+
std::pair<msc_file_handler *, FILE *> SharedFiles::add_new_handler(
5051
const std::string &fileName, std::string *error) {
5152
int shm_id;
53+
int ret;
5254
key_t mem_key_structure;
5355
msc_file_handler_t *new_debug_log;
56+
struct shmid_ds shared_mem_info;
5457
FILE *fp;
5558
bool toBeCreated = true;
5659

@@ -67,8 +70,8 @@ msc_file_handler_t *SharedFiles::add_new_handler(
6770
goto err_mem_key;
6871
}
6972

70-
shm_id = shmget(mem_key_structure, sizeof (msc_file_handler_t) + fileName.size() + 1,
71-
IPC_CREAT | IPC_EXCL | 0666);
73+
shm_id = shmget(mem_key_structure, sizeof (msc_file_handler_t) \
74+
+ fileName.size() + 1, IPC_CREAT | IPC_EXCL | 0666);
7275
if (shm_id < 0) {
7376
shm_id = shmget(mem_key_structure, sizeof (msc_file_handler_t)
7477
+ fileName.size() + 1, IPC_CREAT | 0666);
@@ -80,6 +83,13 @@ msc_file_handler_t *SharedFiles::add_new_handler(
8083
}
8184
}
8285

86+
ret = shmctl(shm_id, IPC_STAT, &shared_mem_info);
87+
if (ret < 0) {
88+
error->assign("Failed to get information on shared memory (1): ");
89+
error->append(strerror(errno));
90+
goto err_shmctl1;
91+
}
92+
8393
new_debug_log = reinterpret_cast<msc_file_handler_t *>(
8494
shmat(shm_id, NULL, 0));
8595
if ((reinterpret_cast<char *>(new_debug_log)[0]) == -1) {
@@ -88,103 +98,143 @@ msc_file_handler_t *SharedFiles::add_new_handler(
8898
goto err_shmat1;
8999
}
90100

101+
if (toBeCreated == false && shared_mem_info.shm_nattch == 0) {
102+
toBeCreated = true;
103+
}
104+
91105
if (toBeCreated) {
92106
memset(new_debug_log, '\0', sizeof(msc_file_handler_t));
93107
pthread_mutex_init(&new_debug_log->lock, NULL);
94-
new_debug_log->fp = fp;
95-
new_debug_log->file_handler = fileno(new_debug_log->fp);
96108
new_debug_log->shm_id_structure = shm_id;
97109
memcpy(new_debug_log->file_name, fileName.c_str(), fileName.size());
98110
new_debug_log->file_name[fileName.size()] = '\0';
99111
}
100-
m_handlers.push_back(std::make_pair(fileName, new_debug_log));
112+
m_handlers.push_back(std::make_pair(fileName,
113+
std::make_pair(new_debug_log, fp)));
101114

102-
return new_debug_log;
115+
return std::make_pair(new_debug_log, fp);
103116
err_shmget1:
117+
err_shmctl1:
104118
err_shmat1:
105119
shmdt(new_debug_log);
106120
err_mem_key:
107121
fclose(fp);
108122
err_fh:
109-
return NULL;
123+
return std::pair<modsecurity::utils::msc_file_handler*,
124+
_IO_FILE*>(NULL, NULL);
110125
}
111126

112127

113128
bool SharedFiles::open(const std::string& fileName, std::string *error) {
114-
msc_file_handler_t *a = find_handler(fileName);
115-
if (a == NULL) {
129+
std::pair<msc_file_handler *, FILE *> a;
130+
131+
#if MODSEC_USE_GENERAL_LOCK
132+
pthread_mutex_lock(m_generalLock);
133+
#endif
134+
135+
a = find_handler(fileName);
136+
if (a.first == NULL) {
116137
a = add_new_handler(fileName, error);
117138
if (error->size() > 0) {
118-
return false;
139+
goto out;
119140
}
120141
}
121-
if (a == NULL) {
142+
if (a.first == NULL) {
122143
error->assign("Not able to open: " + fileName);
123-
return false;
144+
goto out;
124145
}
125146

126-
a->using_it++;
147+
out:
148+
#if MODSEC_USE_GENERAL_LOCK
149+
pthread_mutex_unlock(m_generalLock);
150+
#endif
127151

128152
return true;
129153
}
130154

131155

132156
void SharedFiles::close(const std::string& fileName) {
133-
msc_file_handler_t *a;
134-
int j = 0;
157+
std::pair<msc_file_handler *, FILE *> a;
158+
/* int ret; */
159+
/* int shm_id; */
160+
/* struct shmid_ds shared_mem_info; */
161+
/* int j = 0; */
162+
163+
#if MODSEC_USE_GENERAL_LOCK
164+
pthread_mutex_lock(m_generalLock);
165+
#endif
135166

136167
if (fileName.empty()) {
137-
return;
168+
goto out;
138169
}
139170

140171
a = find_handler(fileName);
141-
if (a == NULL) {
142-
return;
172+
if (a.first == NULL || a.second == NULL) {
173+
goto out;
143174
}
144175

145-
a->using_it--;
146-
147-
if (a->using_it == 0) {
148-
int shm_id1 = a->shm_id_structure;
149-
msc_file_handler_t *p , *n;
150-
pthread_mutex_lock(&a->lock);
151-
fclose(a->fp);
152-
pthread_mutex_unlock(&a->lock);
153-
pthread_mutex_destroy(&a->lock);
154-
shmdt(a);
155-
shmctl(shm_id1, IPC_RMID, NULL);
156-
}
176+
/* fclose(a.second); */
177+
a.second = 0;
157178

158-
for (const auto &i: m_handlers) {
179+
/*
180+
* Delete the file structure will be welcomed, but we cannot delay
181+
* while the process is being killed.
182+
*
183+
for (std::pair<std::string,
184+
std::pair<msc_file_handler *, FILE *>> i : m_handlers) {
159185
if (i.first == fileName) {
160186
j++;
161187
}
162188
}
163189
164-
m_handlers.erase(m_handlers.begin() + j, m_handlers.begin() + j + 1);
190+
m_handlers.erase(m_handlers.begin()+j);
191+
*/
192+
193+
/* hmdt(a.second); */
194+
shmctl(a.first->shm_id_structure, IPC_RMID, NULL);
195+
196+
/*
197+
*
198+
* We could check to see how many process attached to the shared memory
199+
* we have, prior to the deletion of the shared memory.
200+
*
201+
ret = shmctl(a.first->shm_id_structure, IPC_STAT, &shared_mem_info);
202+
if (ret < 0) {
203+
goto out;
204+
}
205+
ret = shared_mem_info.shm_nattch;
206+
shm_id = a.first->shm_id_structure;
207+
*/
208+
209+
out:
210+
#if MODSEC_USE_GENERAL_LOCK
211+
pthread_mutex_unlock(m_generalLock);
212+
#endif
213+
return;
165214
}
166215

167216

168217
bool SharedFiles::write(const std::string& fileName,
169218
const std::string &msg, std::string *error) {
219+
std::pair<msc_file_handler *, FILE *> a;
170220
std::string lmsg = msg;
171221
size_t wrote;
172222
bool ret = true;
173223

174-
msc_file_handler_t *a = find_handler(fileName);
175-
if (a == NULL) {
224+
a = find_handler(fileName);
225+
if (a.first == NULL) {
176226
error->assign("file is not open: " + fileName);
177227
return false;
178228
}
179229

180-
pthread_mutex_lock(&a->lock);
230+
pthread_mutex_lock(&a.first->lock);
181231
wrote = fwrite(reinterpret_cast<const char *>(lmsg.c_str()), 1,
182-
lmsg.size(), a->fp);
232+
lmsg.size(), a.second);
183233
if (wrote < msg.size()) {
184234
error->assign("failed to write: " + fileName);
185235
ret = false;
186236
}
187-
pthread_mutex_unlock(&a->lock);
237+
pthread_mutex_unlock(&a.first->lock);
188238

189239
return ret;
190240
}

src/utils/shared_files.h

+85-9
Original file line numberDiff line numberDiff line change
@@ -17,26 +17,39 @@
1717
#define SRC_UTILS_SHARED_FILES_H_
1818

1919

20+
#include <errno.h>
21+
#include <fcntl.h>
22+
#include <pthread.h>
2023
#include <stdio.h>
24+
#include <stdlib.h>
25+
#include <string.h>
2126
#include <sys/ipc.h>
2227
#include <sys/shm.h>
28+
#include <sys/stat.h>
2329
#include <sys/types.h>
30+
#include <unistd.h>
2431

32+
#include <utility>
33+
#include <vector>
34+
#include <fstream>
2535
#include <string>
2636

37+
2738
#include "modsecurity/transaction.h"
2839
#include "modsecurity/audit_log.h"
2940

41+
/**
42+
* Not using this critical section yet.
43+
*
44+
*/
45+
/* #define MODSEC_USE_GENERAL_LOCK */
3046

3147
namespace modsecurity {
3248
namespace utils {
3349

3450

3551
typedef struct msc_file_handler {
36-
FILE *fp;
37-
int file_handler;
3852
int shm_id_structure;
39-
int using_it;
4053
pthread_mutex_t lock;
4154
char file_name[];
4255
} msc_file_handler_t;
@@ -48,19 +61,77 @@ class SharedFiles {
4861
void close(const std::string& fileName);
4962
bool write(const std::string& fileName, const std::string &msg,
5063
std::string *error);
64+
5165
static SharedFiles& getInstance() {
5266
static SharedFiles instance;
5367
return instance;
5468
}
5569

5670
protected:
57-
msc_file_handler_t *find_handler(const std::string &fileName);
58-
msc_file_handler_t *add_new_handler(const std::string &fileName,
59-
std::string *error);
71+
std::pair<msc_file_handler *, FILE *> find_handler(
72+
const std::string &fileName);
73+
std::pair<msc_file_handler *, FILE *> add_new_handler(
74+
const std::string &fileName, std::string *error);
6075

6176
private:
62-
SharedFiles() { }
63-
~SharedFiles() { }
77+
SharedFiles()
78+
#ifdef MODSEC_USE_GENERAL_LOCK
79+
: m_generalLock(NULL)
80+
#endif
81+
{
82+
#ifdef MODSEC_USE_GENERAL_LOCK
83+
int shm_id;
84+
bool toBeCreated = true;
85+
bool err = false;
86+
87+
m_memKeyStructure = ftok(".", 1);
88+
if (m_memKeyStructure < 0) {
89+
err = true;
90+
goto err_mem_key;
91+
}
92+
93+
shm_id = shmget(m_memKeyStructure, sizeof(pthread_mutex_t),
94+
IPC_CREAT | IPC_EXCL | 0666);
95+
if (shm_id < 0) {
96+
shm_id = shmget(m_memKeyStructure, sizeof(pthread_mutex_t),
97+
IPC_CREAT | 0666);
98+
toBeCreated = false;
99+
if (shm_id < 0) {
100+
err = true;
101+
goto err_shmget1;
102+
}
103+
}
104+
105+
m_generalLock = reinterpret_cast<pthread_mutex_t *>(
106+
shmat(shm_id, NULL, 0));
107+
if ((reinterpret_cast<char *>(m_generalLock)[0]) == -1) {
108+
err = true;
109+
goto err_shmat1;
110+
}
111+
112+
if (toBeCreated) {
113+
memset(m_generalLock, '\0', sizeof(pthread_mutex_t));
114+
pthread_mutex_init(m_generalLock, NULL);
115+
pthread_mutex_unlock(m_generalLock);
116+
}
117+
118+
if (err) {
119+
err_mem_key:
120+
std::cerr << strerror(errno) << std::endl;
121+
err_shmget1:
122+
std::cerr << "err_shmget1" << std::endl;
123+
err_shmat1:
124+
std::cerr << "err_shmat1" << std::endl;
125+
}
126+
toBeCreated = false;
127+
#endif
128+
}
129+
~SharedFiles() {
130+
#if MODSEC_USE_GENERAL_LOCK
131+
shmdt(m_generalLock);
132+
shmctl(m_memKeyStructure, IPC_RMID, NULL);
133+
#endif
134+
}
64135

65136
// C++ 03
66137
// ========
@@ -70,7 +141,12 @@ class SharedFiles {
70141
SharedFiles(SharedFiles const&);
71142
void operator=(SharedFiles const&);
72143

73-
std::vector<std::pair<std::string, msc_file_handler *>> m_handlers;
144+
std::vector<std::pair<std::string,
145+
std::pair<msc_file_handler *, FILE *>>> m_handlers;
146+
#if MODSEC_USE_GENERAL_LOCK
147+
pthread_mutex_t *m_generalLock;
148+
key_t m_memKeyStructure;
149+
#endif
74150
};
75151

76152

0 commit comments

Comments
 (0)