rendered paste body/******************************************************************************** * The following functions manage InterProcess Communication ********************************************************************************/#include "ipc.h"#include "image.h"#include <stdlib.h>#include <sys/ipc.h>#include <sys/sem.h>#include <sys/shm.h>#include <sys/msg.h>#define SERVER_MESSAGE_ID 1#define CLIENT_MESSAGE_ID 2struct mymsgbuf{ long mtype; int width; int height; };void *manageJPEGUpdates (void *arg){ key_t key; int sem_id, msq_id, shm_id; int width, height; char *shmsegptr; int length; struct mymsgbuf msg; // Initialize IPC key = create_key(); sem_id = init_semaphore( key ); msq_id = init_message_queue( key, &width, &height ); shm_id = init_shared_memory( key, width, height, shmsegptr ); length = sizeof(struct mymsgbuf) - sizeof(long); // Listen for update messages while (1) { // Get message if (msgrcv(msq_id, &msg, length, SERVER_MESSAGE_ID, 0) == -1) { perror("manageJPEGUpdates: msgrcv() failed"); } czsImgClr img; img.w = width; img.h = height; img.data = shmsegptr; czfWriteImgPPM(img, "test.ppm"); // Update JPEG createJPEG ((imageJPEG *) arg, sem_id, shmsegptr, width, height); }}key_t create_key (){ key_t key; if ((key = ftok( "/myApp", 'c' )) == -1) { perror("create_key: ftok() failed"); return (-1); } else { return (key); }}// Initialize semaphore setint init_semaphore(key_t key){ int sem_id; if ((sem_id = semget(key, 1, 0666)) == -1) { perror("init_semaphore: semget() failed"); return (-1); } return (sem_id);}// Lock semaphore (BLOCKING !)void semaphore_lock (int sem_id){ struct sembuf sem_lock = {0, -1, 0}; if (semop(sem_id, &sem_lock, 1) == -1) { perror("semaphore_lock: semop() failed"); }}// Unlock semaphorevoid semaphore_unlock (int sem_id){ struct sembuf sem_unlock = {0, 1, 0}; if (semop(sem_id, &sem_unlock, 1) == -1) { perror("semaphore_unlock: semop() failed"); }}// Initialize message queueint init_message_queue( key_t key, int *width, int *height ){ int msq_id, length; struct mymsgbuf msg, ack; /* Open the message queue */ if ((msq_id = msgget(key, 0666)) == -1) { perror("init_message_queue: msgget() failed"); return (-1); } ack.mtype = CLIENT_MESSAGE_ID; length = sizeof(struct mymsgbuf) - sizeof(long); /* Receive initial width and height */ if (msgrcv(msq_id, &msg, length, SERVER_MESSAGE_ID, 0) == -1) { perror("init_message_queue: msgrcv() failed"); return (-1); } *width = ack.width = msg.width; *height = ack.height = msg.height; /* Acknowledge this width and height to the server */ if (msgsnd(msq_id, &ack, length, 0) == -1) { perror("init_message_queue: msgrcv() failed"); return (-1); } return (msq_id);}// Initialize shared memory segmentint init_shared_memory(key_t key, int width, int height, char *shmsegptr){ int shm_id; if ((shm_id = shmget(key, width * height * 3, 0666)) == -1) { perror("init_shared_memory(): shmget failed"); return (-1); } if ((shmsegptr = (char *) shmat(shm_id, 0, 0 )) == (char *) -1) { perror("init_shared_memory(): shmat failed"); return (-1); } printf("\n\n%d\n\n", *shmsegptr); return (shm_id);}