ftrylockfile.c raw

   1  #include "stdio_impl.h"
   2  #include "pthread_impl.h"
   3  #include <limits.h>
   4  
   5  void __do_orphaned_stdio_locks()
   6  {
   7  	FILE *f;
   8  	for (f=__pthread_self()->stdio_locks; f; f=f->next_locked)
   9  		a_store(&f->lock, 0x40000000);
  10  }
  11  
  12  void __unlist_locked_file(FILE *f)
  13  {
  14  	if (f->lockcount) {
  15  		if (f->next_locked) f->next_locked->prev_locked = f->prev_locked;
  16  		if (f->prev_locked) f->prev_locked->next_locked = f->next_locked;
  17  		else __pthread_self()->stdio_locks = f->next_locked;
  18  	}
  19  }
  20  
  21  void __register_locked_file(FILE *f, pthread_t self)
  22  {
  23  	f->lockcount = 1;
  24  	f->prev_locked = 0;
  25  	f->next_locked = self->stdio_locks;
  26  	if (f->next_locked) f->next_locked->prev_locked = f;
  27  	self->stdio_locks = f;
  28  }
  29  
  30  int ftrylockfile(FILE *f)
  31  {
  32  	pthread_t self = __pthread_self();
  33  	int tid = self->tid;
  34  	int owner = f->lock;
  35  	if ((owner & ~MAYBE_WAITERS) == tid) {
  36  		if (f->lockcount == LONG_MAX)
  37  			return -1;
  38  		f->lockcount++;
  39  		return 0;
  40  	}
  41  	if (owner < 0) f->lock = owner = 0;
  42  	if (owner || a_cas(&f->lock, 0, tid))
  43  		return -1;
  44  	__register_locked_file(f, self);
  45  	return 0;
  46  }
  47