xref: /plan9-contrib/sys/src/lib9p/fid.c (revision 7dd7cddf99dd7472612f1413b4da293630e6b1bc)
1 #include <u.h>
2 #include <libc.h>
3 #include <auth.h>
4 #include <fcall.h>
5 #include <thread.h>
6 #include "9p.h"
7 
8 struct Fidpool {
9 	Intmap	*map;
10 };
11 
12 static void
13 incfidref(void *v)
14 {
15 	Fid *f;
16 
17 	f = v;
18 	if(f)
19 		incref(&f->ref);
20 }
21 
22 Fidpool*
23 allocfidpool(void)
24 {
25 	Fidpool *f;
26 
27 	if((f = mallocz(sizeof *f, 1)) == nil)
28 		return nil;
29 	if((f->map = allocmap(incfidref)) == nil){
30 		free(f);
31 		return nil;
32 	}
33 	return f;
34 }
35 
36 Fid*
37 allocfid(Fidpool *fpool, ulong fid)
38 {
39 	Fid *f;
40 
41 	if((f = mallocz(sizeof *f, 1)) == nil)
42 		return nil;
43 
44 	f->fid = fid;
45 	f->omode = -1;
46 	f->pool = fpool;
47 
48 	incfidref(f);
49 	if(!caninsertkey(fpool->map, fid, f)){
50 		closefid(f);
51 		return nil;
52 	}
53 
54 	return f;
55 }
56 
57 int
58 closefid(Fid *f)
59 {
60 	int n;
61 	int fid;
62 
63 	fid = f->fid;
64 	if((n = decref(&f->ref)) == 0) {
65 		if(f->file)
66 			fclose(f->file);
67 		free(f);
68 	}
69 if(lib9p_chatty)
70 	fprint(2, "closefid %d %p: %ld refs\n", fid, f, n ? f->ref.ref : n);
71 	return n;
72 }
73 
74 void
75 freefid(Fid *f)
76 {
77 	Fid *nf;
78 
79 	if(f == nil)
80 		return;
81 
82 	nf = deletekey(f->pool->map, f->fid);
83 	assert(f == nf);
84 
85 	if(closefid(f) == 0)	/* can't be last one; we have one more */
86 		abort();
87 	closefid(f);
88 }
89 
90 Fid*
91 lookupfid(Fidpool *fpool, ulong fid)
92 {
93 	return lookupkey(fpool->map, fid);
94 }
95