Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- #include <signal.h>
- #include <unistd.h>
- #include <sys/types.h>
- #include <sys/ipc.h>
- #include <sys/msg.h>
- #include <pthread.h>
- #include "shared_data.h"
- #define MAX 999
- /* removed some structs */
- typedef struct {
- pthread_t thread;
- int status;
- } thread;
- typedef struct {
- int key;
- thread * t;
- } threadInfo;
- student db[MAX];
- int size;
- int id; // main message queue
- int currentConnections;
- int maxConnections;
- int flushTimer;
- unsigned int lastKey;
- char * databaseFile;
- /* There were more methods here, but I removed them for the sake of saving space */
- void saveData() {
- FILE * fp;
- fp = fopen(databaseFile, "wb");
- fwrite(db, sizeof(student), size, fp);
- fclose(fp);
- }
- void alarmHandler(int signum){
- saveData();
- alarm(5);
- }
- void ctrlcHandler(int signum) {
- char c = 'a';
- printf("\nExit? (y/n): ");
- while(c != 'y' && c != 'n')
- scanf("%c",&c);
- if (c == 'y') {
- saveData();
- msgctl(id, IPC_RMID, NULL);
- exit(1);
- }
- }
- void * client(void * t) {
- threadInfo * t_info = (threadInfo *)t;
- printf("i am the thread with msgq %d\n", t_info->key);
- int msg = msgget(t_info->key, IPC_CREAT|0666);
- CommandRequest req;
- msgrcv(msg, &req, sizeof(CommandRequest), CLIENT_TAG, 0);
- switch(req.c) {
- case DISCONNECT:
- msgctl(msg, IPC_RMID, NULL);
- printf("client disconnected\n");
- t_info->t->status = 0;
- currentConnections--;
- break;
- }
- return NULL;
- }
- void run(){
- thread threads[maxConnections];
- int k = 0;
- for(; k < maxConnections ; k++) threads[k].status = 1;
- if (signal(SIGALRM, alarmHandler) == SIG_ERR) {
- perror("Error installing SIGALRM signal handler");
- }
- if (signal(SIGINT, ctrlcHandler) == SIG_ERR) {
- perror("Error installing SIGINT signal handler");
- }
- alarm(flushTimer);
- id = msgget(PUBLIC_KEY, IPC_CREAT|0666);
- if (id == -1) {
- perror("msgget");
- exit(1);
- }
- while(1) {
- CommandRequest req;
- msgrcv(id, &req, sizeof(CommandRequest), CLIENT_TAG, 0); //receive connect request
- printf("\"%c\"\n", req.c);
- if (req.c == CONNECT) {
- ConnectResponse resp;
- if (currentConnections < maxConnections) {
- printf("client has connected\n");
- int i = 0;
- resp.c = OK;
- resp.key = lastKey++;
- int clientmsgq = msgget(resp.key, IPC_CREAT|0666);
- currentConnections++;
- for (;i < maxConnections && !threads[i].status;i++);
- if (i != maxConnections) {
- threadInfo t_info;
- t_info.t = &threads[i];
- t_info.key = resp.key;
- pthread_create(&(threads[i].thread), NULL, &client, &t_info);
- printf("thread created\n");
- }
- }
- else {
- resp.c = ERROR;
- resp.key = -1;
- }
- resp.mtype = SERVER_TAG;
- msgsnd(id, &resp, sizeof(ConnectResponse), 0);
- }
- }
- }
- int main(int argc, char ** argv){
- maxConnections = atoi(argv[1]);
- flushTimer = atoi(argv[2]);
- databaseFile = argv[3];
- lastKey = PUBLIC_KEY + 1;
- run();
- return 0;
- }
Add Comment
Please, Sign In to add comment