Skip to content

Commit 3691206

Browse files
authored
Fixed Crashes.
The server now doesn't crash if multiple clients send millions of requests per second.
1 parent 088064a commit 3691206

10 files changed

Lines changed: 79 additions & 78 deletions

File tree

Client.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ void fallback(void)
1111
void main(void)
1212
{
1313
memclient = memc_open();
14-
printf("%d\n", *(char*)memclient->socket);
1514
atexit(&fallback);
1615
signal(SIGINT, exit);
1716

@@ -21,12 +20,12 @@ void main(void)
2120
printf("Send Message: ");
2221
scanf("%[^\n]", &message);
2322
memc_send(memclient, &message, strlen(&message));
24-
printf("%d\n", *(char*)memclient->socket);
25-
printf("Recieved Answer: %s\n", memclient->socket+3);
23+
printf("%d\n", *(char*)memclient->con.socket);
24+
printf("Recieved Answer: %s\n", memclient->con.socket);
2625
memc_accept(memclient);
27-
printf("%d\n", *(char*)memclient->socket);
26+
printf("%d\n", *(char*)memclient->con.socket);
2827
#elif defined(performance)
29-
for(unsigned long long l = 0;l < 1000001; ++l)
28+
for(unsigned long long l = 0;l < 1000000; ++l)
3029
{
3130
memc_send(memclient, &l, 8);
3231
memc_accept(memclient);
@@ -39,11 +38,12 @@ void main(void)
3938
char answer[DEFAULT_CONNECTION_BUFFER_SIZE];
4039
sprintf(&message, "cli: %lld", l);
4140
memc_send(memclient, &message, strlen(&message)+1);
42-
strcpy(&answer, memclient->socket+3);
41+
//strcpy(&answer, memclient->con.socket);
4342
//sleep(1);
43+
printf("Recieved Answer: %s\n", memclient->con.socket);
4444
memc_accept(memclient);
4545
printf("Sent message: %s\n", &message);
46-
printf("Recieved Answer: %s\n", &answer);
46+
//printf("Recieved Answer: %s\n", &answer);
4747
}
4848
#endif
4949
}

Client.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,6 @@
22

33
#include <signal.h>
44
#include <stdio.h>
5+
#include "MemoryConnection.h"
56

67
void main();

MemClient.c

Lines changed: 19 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -3,44 +3,34 @@
33
MemClient* memc_open()
44
{
55
MemClient* ret = (MemClient*)malloc(sizeof(MemClient));
6-
/* create semaphore */
7-
ret->socket_lock_server = sem_open(DEFAULT_SERVER_SEMAPHORE_NAME, O_CREAT /* only open if it exists*/, 0644, 1);
8-
if (ret->socket_lock_server == SEM_FAILED) {
9-
perror("sem_open");
10-
exit(-1);
11-
}
126
/* create shared memory */
13-
ret->shm_id = shmget(ftok(DEFAULT_CONNECTION_SHM, 0), DEFAULT_CONNECTION_BUFFER_SIZE, 0666); // create shared memory
7+
ret->con.shm_id = shmget(ftok(DEFAULT_CONNECTION_SHM, 0), DEFAULT_CONNECTION_BUFFER_SIZE, 0666); // create shared memory
148

159
/* check if shared memory was created successfully */
16-
if (ret->shm_id == -1)
10+
if (ret->con.shm_id == -1)
1711
{
1812
perror("Check if server is running, Error creating shared memory");
19-
if (sem_unlink(DEFAULT_SERVER_SEMAPHORE_NAME) == -1)
20-
perror("sem_unlink");
2113
_Exit(-1);
2214
}
2315

2416
/* attach shared memory to the process's address space */
25-
ret->socket = shmat(ret->shm_id, (void*) 0, 0);
26-
if (ret->socket == (char*) -1)
17+
ret->con.socket = shmat(ret->con.shm_id, (void*) 0, 0);
18+
if (ret->con.socket == (char*) -1)
2719
{
2820
perror("Error attaching shared memory");
2921
return 1;
3022
}
3123

32-
ret->socket+=3;
24+
ret->con.socket+=3;
3325

3426
if(memcon_getState(ret) == MCON_UNVAIL)
3527
{
3628
printf("Error: Server not running.\n");
37-
/* unlink, since no server running and shared memory not needed */
38-
if (sem_unlink(DEFAULT_SERVER_SEMAPHORE_NAME) == -1)
39-
perror("sem_unlink");
40-
if (shmdt(ret->socket) == -1)
29+
30+
if (shmdt(ret->con.socket) == -1)
4131
perror("Error detaching shared memory");
4232
/* mark shared memory for removal */
43-
if (shmctl(ret->shm_id, IPC_RMID, NULL) == -1)
33+
if (shmctl(ret->con.shm_id, IPC_RMID, NULL) == -1)
4434
perror("Error removing shared memory");
4535
free(ret);
4636
_Exit(-1);
@@ -50,31 +40,33 @@ MemClient* memc_open()
5040

5141
void memc_send(MemClient* client, void* data, _nmap_size size)
5242
{
43+
client->active = CLIENT_ACTIVE;
5344
// printf("MemClient.c:53 wait\n");
54-
memcon_awaitAndSetState(MCON_EMPTY, MCON_TRANSFER, client);
55-
memcpy(client->socket+3, data, size);
56-
memcon_updateState(MCON_WAITING, client);
57-
sem_post(client->socket_lock_server);
45+
memcon_awaitAndSetState(MCON_EMPTY, MCON_TRANSFER, &client->con);
46+
memcpy(client->con.socket, data, size);
47+
memcon_updateState(MCON_WAITING, &client->con);
5848
// printf("MemClient.c:58 wait\n");
59-
memcon_awaitState(MCON_RESPONSED, client);
49+
memcon_awaitState(MCON_RESPONSED, &client->con);
6050
// printf("MemClient.c:60 done\n");
6151
}
6252

6353
extern inline void memc_cleanbuf(MemClient* client)
6454
{
65-
memset(client->socket + 3, 0, DEFAULT_CONNECTION_BUFFER_SIZE);
55+
memset(client->con.socket, 0, DEFAULT_CONNECTION_BUFFER_SIZE);
6656
}
6757

6858
extern inline void memc_accept(MemClient* client)
6959
{
70-
memcon_updateState(MCON_EMPTY, client);
60+
memcon_updateState(MCON_EMPTY, &client->con);
61+
client->active = CLIENT_INACTIVE;
7162
}
7263

7364
void memc_close(MemClient* client)
7465
{
75-
sem_close(client->socket_lock_server);
66+
if(client->active == CLIENT_ACTIVE)
67+
memcon_updateState(MCON_EMPTY, &client->con);
7668
/* detach shared memory */
77-
if (shmdt(client->socket - 3) == -1)
69+
if (shmdt(client->con.socket - 3) == -1)
7870
{
7971
perror("Error detaching shared memory");
8072
_Exit(-1);

MemClient.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,13 @@
1616
#include "null.h"
1717
#include "NMap_types.h"
1818

19-
typedef struct _MemCon MemClient;
19+
typedef struct _MemClient MemClient;
20+
21+
struct _MemClient
22+
{
23+
struct _MemCon con;
24+
unsigned char active;
25+
};
2026

2127
MemClient* memc_open();
2228
/* waits until a message is sent to socket

MemServer.c

Lines changed: 21 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -3,75 +3,67 @@
33
MemServer* mems_open()
44
{
55
MemServer* ret = (MemServer*)malloc(sizeof(MemServer));
6-
/* create semaphore */
7-
ret->socket_lock_server = sem_open(DEFAULT_SERVER_SEMAPHORE_NAME, O_CREAT, 0644, 1);
8-
if (ret->socket_lock_server == SEM_FAILED) {
9-
perror("sem_open");
10-
exit(-1);
11-
}
126
/* create shared memory */
13-
ret->shm_id = shmget(ftok(DEFAULT_CONNECTION_SHM, 0), DEFAULT_CONNECTION_BUFFER_SIZE, IPC_CREAT | 0666); // create shared memory
7+
ret->con.shm_id = shmget(ftok(DEFAULT_CONNECTION_SHM, 0), DEFAULT_CONNECTION_BUFFER_SIZE, IPC_CREAT | 0666); // create shared memory
148

159
/* check if shared memory was created successfully */
16-
if (ret->shm_id == -1)
10+
if (ret->con.shm_id == -1)
1711
{
1812
perror("Error creating shared memory");
19-
return 1;
13+
_Exit(-1);
2014
}
2115

2216
/* attach shared memory to the process's address space */
23-
ret->socket = shmat(ret->shm_id, (void*) 0, 0);
24-
if (ret->socket == (char*) -1)
17+
ret->con.socket = shmat(ret->con.shm_id, (void*) 0, 0);
18+
if (ret->con.socket == (char*) -1)
2519
{
2620
perror("Error attaching shared memory");
27-
return 1;
21+
_Exit(-1);
2822
}
2923

30-
memset(ret->socket, 0, DEFAULT_CONNECTION_BUFFER_SIZE);
31-
ret->socket+=3;
32-
memcon_updateState(MCON_EMPTY, ret);
33-
*((char*)ret->update1) = UPDATE_NONE;
24+
memset(ret->con.socket, 0, DEFAULT_CONNECTION_BUFFER_SIZE);
25+
ret->con.socket+=3;
26+
memcon_updateState(MCON_EMPTY, &ret->con);
27+
*((char*)ret->con.update1) = UPDATE_NONE;
3428
return ret;
3529
}
3630

3731
void mems_wait(MemServer* server)
3832
{
3933
// printf("MemServer.c:42 wait\n");
40-
memcon_awaitState(MCON_WAITING, server);
34+
memcon_awaitState(MCON_WAITING, &server->con);
4135
// printf("MemServer.c:44 done\n");
4236
}
4337

4438
extern inline void mems_cleanbuf(MemServer* server)
4539
{
46-
memset(server->socket +3, 0, DEFAULT_CONNECTION_BUFFER_SIZE);
40+
memset(server->con.socket, 0, DEFAULT_CONNECTION_BUFFER_SIZE);
4741
}
4842

4943
extern inline void mems_answer(MemServer* server, void* data, _nmap_size size)
5044
{
5145
// printf("answering\n");
52-
memcpy(server->socket+3, data, size);
46+
memcpy(server->con.socket, data, size);
5347
// printf("answered\n");
54-
memcon_updateState(MCON_RESPONSED, server);
48+
memcon_updateState(MCON_RESPONSED, &server->con);
5549
}
5650

5751
void mems_close(MemServer* server)
5852
{
59-
*((char*)server->socket) = MCON_UNVAIL;
60-
sem_close(server->socket_lock_server);
61-
sem_unlink(DEFAULT_SERVER_SEMAPHORE_NAME);
53+
memcon_updateState(MCON_UNVAIL, &server->con);
6254

63-
// detach shared memory from process's address space
64-
if (shmdt(server->socket-3) == -1)
55+
/* detach shared memory from process's address space*/
56+
if (shmdt(server->con.socket-3) == -1)
6557
{
6658
perror("Error detaching shared memory");
67-
return 1;
59+
_Exit(-1);
6860
}
6961

70-
// mark shared memory for removal
71-
if (shmctl(server->shm_id, IPC_RMID, NULL) == -1)
62+
/* mark shared memory for removal*/
63+
if (shmctl(server->con.shm_id, IPC_RMID, NULL) == -1)
7264
{
7365
perror("Error removing shared memory");
74-
return 1;
66+
_Exit(-1);
7567
}
7668
free(server);
7769
}

MemServer.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,12 @@
1616
#include "null.h"
1717
#include "NMap_types.h"
1818

19-
typedef struct _MemCon MemServer;
19+
typedef struct _MemServer MemServer;
20+
21+
struct _MemServer
22+
{
23+
struct _MemCon con;
24+
};
2025

2126
MemServer* mems_open();
2227
extern inline void mems_answer(MemServer* server, void* data, _nmap_size size);

MemoryConnection.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,7 @@ extern inline void memcon_awaitState(enum _ConnectionState state_wait, struct _M
3636
for(int w = 0;;)
3737
{
3838
for(;w < 5; ++w)
39-
{
40-
//printf("%d\n", *((char*)con->state1));
39+
{;
4140
if(*((char*)con->state1) == state_wait)
4241
{
4342
if(*((char*)con->update1) != UPDATE)
@@ -46,7 +45,6 @@ extern inline void memcon_awaitState(enum _ConnectionState state_wait, struct _M
4645
}
4746
for(;w > -1; --w)
4847
{
49-
//printf("%d\n", *((char*)con->state2));
5048
if(*((char*)con->state2) == state_wait)
5149
{
5250
if(*((char*)con->update1) != UPDATE)
@@ -58,9 +56,12 @@ extern inline void memcon_awaitState(enum _ConnectionState state_wait, struct _M
5856

5957
extern inline void memcon_updateState(enum _ConnectionState state_new, struct _MemCon* con)
6058
{
59+
// critical change, didnt found a fix except for waiting
6160
memcon_setUpdate(UPDATE,con);
61+
// usleep(10000);
6262
*((char*)con->state1) = state_new;
6363
*((char*)con->state2) = state_new;
64+
// usleep(10000);
6465
memcon_setUpdate(UPDATE_NONE,con);
6566
}
6667

MemoryConnection.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,16 @@ typedef void* _mem_socket;
4040
UPDATE_NONE
4141
};
4242

43+
enum _ClientState
44+
{
45+
CLIENT_INACTIVE,
46+
CLIENT_ACTIVE
47+
};
48+
4349
struct _MemCon
4450
{
4551
_mem_socket socket;
4652
int shm_id;
47-
sem_t*socket_lock_server;
4853
};
4954

5055
extern inline void memcon_awaitAndSetState(enum _ConnectionState state_wait, enum _ConnectionState state_new, struct _MemCon* con);

Server.c

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,32 +16,31 @@ void main(void)
1616
memserver = mems_open();
1717
#ifdef messanger
1818
mems_wait(memserver);
19-
printf("Recieved Message: %s\n", memserver->socket+1);
19+
printf("Recieved Message: %s\n", memserver->con.socket);
2020
printf("Send answer: ");
2121
char answer[DEFAULT_CONNECTION_BUFFER_SIZE];
2222
scanf("%[^\n]", &answer);
23-
mems_answer(memserver, &answer, strlen(&answer));
23+
mems_answer(memserver, &answer, strlen(&answer)+1);
2424
exit(0);
2525
#elif defined(performance)
2626
long long l;
2727
long long answer = 1;
2828
for(;;)
2929
{
3030
mems_wait(memserver);
31-
l = *(long long*)(((char*)memserver->socket) + 3);
31+
l = *(long long*)(((char*)memserver->con.socket));
3232
mems_answer(memserver, &answer, 8);
3333
if(l % 10000 == 0)
3434
printf("%lld\n", l);
3535
}
3636
#else
37+
char answer[DEFAULT_CONNECTION_BUFFER_SIZE];
3738
for(long long l;++l;)
3839
{
3940
mems_wait(memserver);
40-
//printf("Recieved Message: %s\n", memserver->socket+1);
41-
char answer[DEFAULT_CONNECTION_BUFFER_SIZE];
41+
printf("Recieved Message: %s\n", memserver->con.socket);
4242
sprintf(&answer, "ser: %d", l);
43-
//sleep(1);
44-
mems_answer(memserver, &answer, strlen(&answer) +1 );
43+
mems_answer(memserver, &answer, strlen(&answer)+1);
4544
}
4645
#endif
4746
}

server.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
# check if GCC is installed
22
if command -v gcc >/dev/null 2>&1; then
33
if [ $# -gt 0 ]; then
4-
c99 Server.c MemoryConnection.c MemServer.c -D$1 -w -O3 -o /tmp/ndbs-out && /tmp/ndbs-out
4+
c99 Server.c SString.c MemoryConnection.c MemServer.c -D$1 -w -O3 -o /tmp/ndbs-out && /tmp/ndbs-out
55
else
6-
c99 Server.c MemoryConnection.c MemServer.c -w -O3 -o /tmp/ndbs-out && /tmp/ndbs-out
6+
c99 Server.c SString.c MemoryConnection.c MemServer.c -w -O3 -o /tmp/ndbs-out && /tmp/ndbs-out
77
fi
88
else
99
echo -e "\033[1m\033[31mError\033[0m: The GNU Compiler Colection GCC isn't installed on your system."

0 commit comments

Comments
 (0)