int client(void)
{
   int s;

   /* spingrab in order to avoid sleep, testcase has a timeout */
   while ( (s = msemgrab(SEM0, 0)) == -1 );

   int cnt = 0;

   for (int i = 0; i < 5; ++i) {
      if (msemdown(s, 1, 1) != 0) {
         if (errno == EINTR) {
            /* interrupted by syscall, try again */
            continue;
         }
         perror("mP(1)");
         break;
      }

      printf("c%d", cnt);
      cnt += 2;
      fflush(stdout);

      if (msemup(s, 1, 0) != 0) {
         perror("mV(0)");
         break;
      }
   }

   return 0;
}
Exemple #2
0
/**
* Write buffer to shared memory
*
* @param data buffer to write to shared memory
*
* @return -1 on error, 0 otherwise
*/
static int ipc_write(char *data)
{

	int ret = -1;

	/* It makes no sense to proceed if nobody is listening */
	ipc_require_listener();

	/*
	 * Firts wait for write queue to let us in 
	 * if cnd or mt are no valid semaphores anymore, another process has already removed them. so we will simply return -1 
	 */
	if(msemdown(cnd, 1, 0) != -1) {

		/* While we are in the mutual exclusive section, we don't listen to signals, because it would be hard to reset the state of the mutex */
		sigset_t blocked_signals, curr_set;
		(void) sigfillset(&blocked_signals);
		(void) sigprocmask(SIG_BLOCK, &blocked_signals, &curr_set);
		
		/* Mutual exclusive section so no other process removes shm segment meanwhile */
		if(semdown(mtx) != -1) {

			if(data == NULL) {

				/* Signal EOF to Listener */
				shared->flag |= EOF_F;

			} else {

				for(int i = 0; i <= MAX_BUF_SIZE; ++i) {

					shared->data[i] = data[i];
					/* Null char */
					if(data[i] == 0) {
						break;
					}
	
				}

			}
	
			ret = (semup(mtx) == -1 ? -1 : 0);
		}

		/* Reset to original procmask*/
		(void) sigprocmask(SIG_SETMASK, &curr_set,  NULL);

		/* Signal read queue to proceed */	
		ret = (msemup(cnd, 1, 1) == -1 ? -1 : 0);

	}
	
	return ret;
}
Exemple #3
0
/**
* Read shared data and calculate statistics
*
* @return -1 on error, 0 on EOF, number of read chars otherwise
*/
static int ipc_process(void) 
{

	int i = -1;

	/*
	 * First, wait for read queue to let us in 
	 * if cnd or mt are no valid semaphores anymore, another process has already removed them. so we will simply return -1 
	 */
	if(msemdown(cnd, 1, 1) != -1) {

		/* While we are in the mutual exclusive section, we don't listen to signals, because it would be hard to reset the state of the mutex */
		sigset_t blocked_signals, curr_set;
		(void) sigfillset(&blocked_signals);
		(void) sigprocmask(SIG_BLOCK, &blocked_signals, &curr_set);
		
		/* Mutual exclusive section so no other process removes shm segment meanwhile */
		if(semdown(mtx) != -1) {

			i = 0;

			/* EOF Flag has been set, return 0 */
			if((shared->flag & EOF_F) != 1) {

				for(i = 0; i <= MAX_BUF_SIZE; ++i) {
	
					int c;
		
					/* Null character */
					if(shared->data[i] == 0) {
						break;
					} 
			
					/* We will only distinguish between uppercase'd chars */	
					c = toupper(shared->data[i]) - ASCII_CHAR_OFFSET;
					if(c < 0 || c > ASCII_CHAR_MAX) { /* No Ascii Letter -> inc 'others' counter */
						shared->stat[ASCII_CHAR_MAX + 1]++;
					} else { /* inc letter counter */
						shared->stat[c]++;
					}
		
					/* Total number of characters */
					shared->total++;
					/* Clear out buffer */
					shared->data[i] = 0;
				
				}
	
			}
	
			if(semup(mtx) == -1) {
				i = -1;
			}

		}

		/* Reset to original procmask*/
		(void) sigprocmask(SIG_SETMASK, &curr_set,  NULL);

		/* Let write queue proceed */
		if(msemup(cnd, 1, 0) == -1) {
			i = -1;
		}

	}
	
	return i;

}