Example #1
0
int main(void)
{
   char *strw = "set write lock on region", *strr = "set read lock on region";
   int fd, bytes_count;
   fd = open(test_file, O_RDWR|O_CREAT, 0666);   /* 開啟檔案 */
   if(fd<0) 
      err_exit("Unable to open file");
   for (bytes_count = 0; bytes_count<100; bytes_count++)  /* 寫入資料 */
      write(fd, "A", 1);              
   if (fork()!=0) {     /* 父執行緒 */
      /* 在區域[10-29]設定共享讀鎖 */
      if (SET_LOCK (fd, F_RDLCK, 10, SEEK_SET, 20)<0)
         fprintf(stderr,"%d %s [10-29] failed\n", getpid(),strr);
      else
         fprintf(stderr,"%d %s [10-29] succeed\n",getpid(),strr);
      /* 在區域[40-49]設定互斥寫鎖 */
      if (SET_LOCK (fd, F_WRLCK, 40, SEEK_SET, 10)<0)
         fprintf(stderr,"%d %s [40-49] failed\n", getpid(),strw);
      else
         fprintf(stderr,"%d %s [40-49] succeed \n",getpid(), strw);
      sleep(3);      /* 睡眠3秒以便子執行緒測試鎖 */
      printf("%d close file\n",getpid());
      close(fd);
      exit(EXIT_SUCCESS);
   } else {         /* 子執行緒 */
      pid_t mypid=getpid(); 
      sleep(1);     /* 讓父執行緒先執行 */
      /* 對區域[10-14]設定讀鎖,與父執行緒設定的讀鎖部分重疊,可成功 */
      if (SET_LOCK (fd, F_RDLCK, 10, SEEK_SET, 5)<0) 
         fprintf(stderr,"%d %s [10-14] failed\n", mypid, strr);
      else 
         fprintf(stderr, "%d %s [10-14] succeed\n", mypid, strr);    
      /* 對區域[15-20]加寫鎖,與父執行緒設定的讀鎖部分重疊,不會成功 */    
      if (SET_LOCK (fd, F_WRLCK, 15,SEEK_SET,6)<0) 
         fprintf(stderr,"%d %s [15-20] failed\n", mypid, strw);
      else 
        fprintf(stderr, "%d %s [15-20]\n", mypid, strw);
      /* 對區域[40-49]加讀鎖,與父執行緒設定的寫鎖重疊,不會成功 */
      if (SET_LOCK (fd, F_RDLCK, 40, SEEK_SET, 10)<0) 
         fprintf(stderr,"%d %s [40-49] failed\n", mypid,strr);
      else 
         fprintf(stderr,"%d %s [40-49] succeed\n", mypid, strr);
      /* 對區域[41-60]加寫鎖並等待,與父執行緒設定的寫鎖重疊,等待父執行緒離開後才會成功 */   
      if (SET_LOCK_W(fd, F_WRLCK, 41, SEEK_SET, 20)<0) 
         fprintf(stderr,"%d %s [41-60] succeed\n", mypid, strw);
      else
         fprintf(stderr,"%d %s [41-60] succeed\n", mypid, strw);
      /* 對區域[0-60]解鎖,將同時釋放區域[10-14]的讀鎖和區域[41-60]的寫鎖 */
      if (un_lock (fd,0,SEEK_SET,69)<0) 
         fprintf(stderr,"%d unlock the region [0-69] failed\n", mypid);
      else 
         fprintf(stderr,"%d unlocked the region [0-69] succeed\n", mypid);
      fprintf(stderr,"Process %d end\n", mypid);    
      close(fd);
      exit(EXIT_SUCCESS);
   }
}
int Condition::timed_lock(int microseconds, const char *location)
{
    struct timeval now;
    struct timespec timeout;
    int result = 0;

#ifndef NO_GUICAST
	SET_LOCK(this, title, location);
#endif
    pthread_mutex_lock(&mutex);
    gettimeofday(&now, 0);
    timeout.tv_sec = now.tv_sec + microseconds / 1000000;
    timeout.tv_nsec = now.tv_usec * 1000 + (microseconds % 1000000) * 1000;

	struct timeval start_time;
	struct timeval new_time;
	int64_t timeout_msec = ((int64_t)microseconds / 1000);
	gettimeofday(&start_time, 0);
    while(value <= 0 && result != ETIMEDOUT)
	{
// This doesn't work in all kernels
//		result = pthread_cond_timedwait(&cond, &mutex, &timeout);
// This is based on the most common frame rate since it's mainly used in
// recording.
	    pthread_mutex_unlock(&mutex);
		usleep(20000);
		gettimeofday(&new_time, 0);
		new_time.tv_usec -= start_time.tv_usec;
		new_time.tv_sec -= start_time.tv_sec;
	    pthread_mutex_lock(&mutex);
		if(value <= 0 && 
			(int64_t)new_time.tv_sec * 1000 + (int64_t)new_time.tv_usec / 1000 > timeout_msec)
			result = ETIMEDOUT;
    }

    if(result == ETIMEDOUT) 
	{
//printf("Condition::timed_lock 1 %s %s\n", title, location);
#ifndef NO_GUICAST
		UNSET_LOCK2
#endif
		result = 1;
    } 
	else 
	{
//printf("Condition::timed_lock 2 %s %s\n", title, location);
#ifndef NO_GUICAST
		UNSET_LOCK2
#endif
		if(is_binary)
			value = 0;
		else
			value--;
		result = 0;
    }
    pthread_mutex_unlock(&mutex);
	return result;
}
Example #3
0
void EncoderPage::update() {
  encoder_t _encoders[GUI_NUM_ENCODERS];

  USE_LOCK();
  SET_LOCK();
  m_memcpy(_encoders, Encoders.encoders, sizeof(_encoders));
  Encoders.clearEncoders();
  CLEAR_LOCK();
  
  for (uint8_t i = 0; i < GUI_NUM_ENCODERS; i++) {
    if (encoders[i] != NULL) 
      encoders[i]->update(_encoders + i);
  }
}
void Condition::lock(const char *location)
{
#ifndef NO_GUICAST
	SET_LOCK(this, title, location);
#endif
    pthread_mutex_lock(&mutex);
    while(value <= 0) pthread_cond_wait(&cond, &mutex);
#ifndef NO_GUICAST
	UNSET_LOCK2
#endif
	if(is_binary)
		value = 0;
	else
		value--;
    pthread_mutex_unlock(&mutex);
}
Example #5
0
int Mutex::lock(const char *location)
{
// Test recursive owner and give up if we already own it
	if(recursive)
	{
		pthread_mutex_lock(&recursive_lock);
		if(thread_id_valid && pthread_self() == thread_id) 
		{
			count++;
			pthread_mutex_unlock(&recursive_lock);
			return 0;
		}
		pthread_mutex_unlock(&recursive_lock);
	}


#ifndef NO_GUICAST
	SET_LOCK(this, title, location);
#endif
	if(pthread_mutex_lock(&mutex)) perror("Mutex::lock");



// Update recursive status for the first lock
	if(recursive)
	{
		pthread_mutex_lock(&recursive_lock);
		count = 1;
		thread_id = pthread_self();
		thread_id_valid = 1;
		pthread_mutex_unlock(&recursive_lock);
	}
	else
	{
		count = 1;
	}


#ifndef NO_GUICAST
	SET_LOCK2
#endif
	return 0;
}