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