All pastes #102360 Raw Edit

Someone

public c v1 · immutable
#102360 ·published 2006-07-27 15:28 UTC
rendered paste body
#include "stdio.h"#include "stdlib.h" #include "string.h"#include "time.h"#include "sys/types.h"#include "sys/ipc.h"#include "sys/msg.h"#include "sys/shm.h"#include "sys/sem.h"#define SERVER_MESSAGE_ID   1#define CLIENT_MESSAGE_ID   2// shared memory to provide the pixmap to an external programint sem_id, shm_id, msq_id;char  *shmsegptr;key_t key;typedef struct mymsgbuf{  long mtype;  int width;  int height;  };key_t create_key (){  key_t key;    if ((key = ftok("/myApp", 'c')) == -1)  {    perror("init_semaphore: ftok() failed");    return(-1);  }  else    return key;}// Initialize semaphore setint init_semaphore(key_t key){  int sem_id;  if ((sem_id = semget(key, 1, IPC_CREAT | IPC_EXCL | 0666)) == -1)  {    if ((sem_id = semget(key, 1, IPC_CREAT | 0666)) == -1)    {      perror("init_semaphore: semget() failed");      return (-1);    }  }    union semun { int val; };  union semun semopts;    semopts.val = 1;  if (semctl(sem_id, 0, SETVAL,  semopts) == -1)  {    perror("init_semaphore: semctl() failed");    return (-1);  }    return sem_id;}// Lock semaphoreint semaphore_lock (int sem_id){  struct sembuf sem_lock = {0, -1, 0};  if (semop(sem_id, &sem_lock, 1) == -1)  {    perror("semaphore_lock:\t\tsemop() failed");    return (-1);  }  else    return (0);}// Unlock semaphoreint semaphore_unlock (int sem_id){  struct sembuf sem_unlock = {0, 1, 0};  if (semop(sem_id, &sem_unlock, 1) == -1)  {    perror("semaphore_unlock:\tsemop() failed");    return (-1);  }  else    return (0);}// Initialize shared memory segmentint init_shared_memory(key_t key, int width, int height){  int shmid;    /* Open the shared memory segment - create if necessary */  if ((shmid = shmget(key, width * height * 3, IPC_CREAT|IPC_EXCL|0666)) == -1)  {    if ((shmid = shmget(key, width * height * 3, IPC_CREAT|0666)) == -1)    {      char error[100];      sprintf(error, "init_shared_memory(%d,%d): shmget failed", width, height);      perror(error);      return (-1);    }  }    /* Attach (map) the shared memory segment into the current process */  if ((shmsegptr = (char *) shmat(shmid, 0, 0)) == (char *) -1)  {    char error[100];    sprintf(error, "init_shared_memory(%d,%d): shmat failed", width, height);    perror(error);    return (-1);  }    return shmid;}// Clear all messages from message queuevoid clear_message_queue (int qid){  struct mymsgbuf msg;  int length;    length = sizeof(struct mymsgbuf) - sizeof(long);  // Loop 1: clear all server messages  while (1)  {    if (msgrcv(qid, &msg, length, 0 | SERVER_MESSAGE_ID, 0 | IPC_NOWAIT) == -1)      break;  }    // Loop 2: clear all client messages  while (1)  {    if (msgrcv(qid, &msg, length, CLIENT_MESSAGE_ID, IPC_NOWAIT) == -1)      break;  }}// Initialize  message queueint init_message_queue( key_t key, int width, int height){  int qid, length;  struct mymsgbuf msg, ack;    /* Open the message queue - create if necessary */  if ((qid = msgget(key, IPC_CREAT | IPC_EXCL | 0666)) == -1)  {    if ((qid = msgget(key, IPC_CREAT | 0666)) == -1)    {      char error[100];      sprintf(error, "init_message_queue(%d,%d): msgget failed", width, height);      perror(error);      return (-1);    }    else    {      /* Clear all messages from the queue, if existant */      clear_message_queue(qid);    }  }    msg.mtype = SERVER_MESSAGE_ID;  msg.width = width;  msg.height = height;  length = sizeof(struct mymsgbuf) - sizeof(long);    /* Send a message with the first size in it */  if (msgsnd(qid, &msg, length, 0) == -1)  {    char error[100];    sprintf(error, "init_message_queue(%d,%d): msgsnd failed", width, height);    perror(error);    return (-1);  }    printf("Waiting for client acknowledgement ... \n");  while (1)  {    /* Wait for the acknowledgement */    if (msgrcv(qid, &ack, length, CLIENT_MESSAGE_ID, 0) == -1)    {      perror("init_message_queue: msgrcv failed");      return (-1);    }        printf("Got client response ...\n");    // Server and client agree on the shm size    if ((msg.height == ack.height) && (msg.width == ack.width)) break;  }  printf("got it!\n");    return qid;}void send_update (){  struct mymsgbuf msg;  msg.mtype = SERVER_MESSAGE_ID;  msg.width = width;  msg.height = height;  int length = sizeof(struct mymsgbuf) - sizeof(long);    /* Send a message with the size in it, thus letting the client know an update is abailible */  if (msgsnd(msq_id, &msg, length, 0) == -1)  {    char error[100];    sprintf(error, "init_message_queue(%d,%d): msgsnd failed", width, height);    perror(error);  }}// General IPC initialization sequencevoid initialize_ipc (int width, int height){  key = create_key();    sem_id = init_semaphore (key);  semaphore_lock (sem_id);  shm_id = init_shared_memory (key, width, height);  printf("shmid: %d\n", shm_id);  msq_id = init_message_queue (key, width, height);  semaphore_unlock (sem_id);  }// Mark message queue for deletionint destroy_message_queue ( int qid ){  if ( msgctl(qid, IPC_RMID, 0) == -1)    return (-1);  else    return (0);}// Mark semaphore set for deletionint destroy_semaphore(int semid){  if (semctl(semid, 0, IPC_RMID, 0) == -1)    return (-1);  else    return (0);}// Free and release shared memory segmentint free_shared_memory (int shmid){  struct shmid_ds shmid_struct;    if (shmdt(shmsegptr) == -1)  {    perror("free_shared_memory(); shmdt failed");    return (-1);  }  if (shmctl(shmid, IPC_RMID, &shmid_struct) == -1)  {    perror("free_shared_memory(); shmctl remove id failed");    return (-1);  }  return (0);}// General IPC cleanup sequencevoid clean_ipc (){  semaphore_lock(sem_id);  free_shared_memory(shm_id);  destroy_message_queue(msq_id);  destroy_semaphore(sem_id);  semaphore_unlock(sem_id);}// Re-initialize shared memory segmentvoid reinit_shared_memory(int width, int height){  semaphore_lock(sem_id);  glViewport(0,0,width,height);}void copy_image_to_shared_memory(){  // Let's see what happens if we change the window_wifth and or window_height  int window_width, window_height;    window_width = glutGet(GLUT_WINDOW_WIDTH);  window_height = glutGet(GLUT_WINDOW_HEIGHT);    czsImgClr img;  czfCreateImgShm( img, window_width, window_height, shmsegptr);    czsImgClr tempImg;  czfCreateImg( tempImg, window_width, window_height );  tempImg.w = window_width;  tempImg.h = window_height;    glReadPixels(0,0, window_width, window_height, GL_RGB, GL_UNSIGNED_BYTE, (GLvoid *) tempImg.data);    semaphore_lock(sem_id);  for (int i = window_height - 1; i >= 0; i--)    for (int j = 0; j < window_width; j++)    {      img.data[((window_height - 1 - i) * (window_width * 3)) + (j*3)] = tempImg.data[(window_width * i * 3) + (j*3)];      img.data[((window_height - 1 - i) * (window_width * 3)) + (j*3) + 1] = tempImg.data[(window_width * i * 3) + (j*3) + 1];      img.data[((window_height - 1 - i) * (window_width * 3)) + (j*3) + 2] = tempImg.data[(window_width * i * 3) + (j*3) + 2];    }  printf("sizeof(char*): %d\n", sizeof(char*));  printf("shmsegptr: %d\n", *shmsegptr);  czfWriteImgPPM(img, "test.ppm");  semaphore_unlock(sem_id);}