/*
 * Class:     sharedmemory_SharedMemory
 * Method:    close_sem
 * Signature: (Ljava/lang/String;)I
 */
JNIEXPORT jint JNICALL Java_sharedmemory_SharedMemory_close_1sem
  (JNIEnv *env, jobject obj, jstring descriptor) {
  jint ret = -1;
  const char* desc = (*env)->GetStringUTFChars( env, descriptor , NULL ) ;
  ret = close_sem(desc);
  (*env)->ReleaseStringUTFChars(env, descriptor ,desc);
  return ret;
}
Ejemplo n.º 2
0
int main(int argc, char ** argv){
  key_t key;
  int *shm_seg, shm_id, sem_id, pid, fd_fifo;
  int i, tmp, count_r;
  int r_arr[2];
  unsigned int nn, n, size;
  struct sigaction sa;
  
  memset(&sa, 0, sizeof(sa));
  sa.sa_handler = sigchldhandler;
  if (sigaction(SIGCHLD, &sa, 0) < 0){
    perror("sigaction");
    exit(0);
  }
  
  printf("n: "); scanf("%u", &n); 
  if (n < 2){ printf("n must be bigger than 1\n"); exit(0); }
  nn = 2;
  while (nn < n){
    nn <<= 1;
  }

  /*-initialize*/
  if (mknod(FIFO, S_IFIFO | 0660, 0) < 0){ perror("mknod: "); exit(2); }
  if ((key = ftok(argv[0], 'q')) < 0) { perror("ftok"); exit(2); }/*========================================================================*/
  size = nn*sizeof(int);
  if ((shm_id = open_seg(key,size)) < 0){ printf("open_seg error\n"); exit(2); }
  if (*(shm_seg = shmat(shm_id, 0, 0)) < 0) { printf("error attaching %d\n",shm_id); exit(2); }
  if ((sem_id = open_sem(key,4)) < 0){ printf("open_sem error\n"); exit(2); }
  
  srand(key);
  for(i = 0; i < n; i++){
    shm_seg[i] = rand() % 100;
    printf("%d ", shm_seg[i]);
  }
  for(; i < nn; i++){
    shm_seg[i] = 100;
    printf("%d ", 100);
  }
  printf("\n");
  
  /*=initialize*/
  
  op_sem(sem_id, &r_unlock[0]);
  op_sem(sem_id, &w_unlock[0]);
  
  for(i = 0; i < nn/2; i++){
    if ((pid = fork()) < 0){ printf("fork %d", i); exit(0); }
    if (pid == 0){
      if ((fd_fifo = open(FIFO, O_RDONLY | O_NONBLOCK)) < 0){ 
				if (errno == EINTR){
					_exit(0);
				}
				perror("open2: "); 
				_exit(2); 
			}
      while (get_sem_val(sem_id, 3) > 0){
        r_arr[0] = 0; r_arr[1] = 0;
        /*
          trouble: В конце работы read читает из пустой фифо. Надо найти макс задержку read'а. Или семафоры...:(
         */
        op_sem(sem_id, &r_lock[0]);
        if ((count_r = read(fd_fifo, &r_arr, sizeof(int)*2)) < 0){
					if (errno == EAGAIN){
						continue;
					}
					perror("read: "); 
					_exit(2);
				};
				if (count_r < 2){ continue; }
        op_sem(sem_id, &iter_unlock[0]);			
        op_sem(sem_id, &r_unlock[0]);
        if (shm_seg[r_arr[0]] > shm_seg[r_arr[1]]){
          tmp = shm_seg[r_arr[0]];
          op_sem(sem_id, &w_lock[0]);
          shm_seg[r_arr[0]] = shm_seg[r_arr[1]];
          shm_seg[r_arr[1]] = tmp;
          op_sem(sem_id, &w_unlock[0]);
        }
      }
      printf("die.\n");
      if (close(fd_fifo) < 0){
				perror("close2");
			}
      _exit(0);
    }
  }
	while (1){
		if ((fd_fifo = open(FIFO, O_WRONLY | O_NONBLOCK)) < 0){ 
			if (errno == EINTR || errno == ENXIO){
				continue;
			}
			perror("open3: "); 
			exit(0); 
		}else{
			break;
		}
	}
  op_sem(sem_id, &work_start[0]);
  make_mn(nn, nn, 1,  fd_fifo, sem_id);
  op_sem(sem_id, &work_stop[0]);
  if (close(fd_fifo) < 0){
		perror("close2");
	};
  for(i = 0; i < n; i++){
    printf("%d ", shm_seg[i]);
  }
	printf("\n");
  while(die < nn/2);
  
  detach_seg((char *)shm_seg);
  close_seg(shm_id);
  close_sem(sem_id);
  return 0;
}