File: fdbuf.c

package info (click to toggle)
tra 20020816-1
  • links: PTS
  • area: main
  • in suites: etch, etch-m68k, sarge
  • size: 1,696 kB
  • ctags: 2,623
  • sloc: ansic: 22,519; makefile: 406; asm: 269
file content (116 lines) | stat: -rw-r--r-- 1,451 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#include "tra.h"

struct Fdmsg
{
	void *a;
	int n;
	Fdmsg *next;
};

void
_fdbufwatch(Fdbuf *b)
{
	Fdmsg *m;
	void *a;
	int n;
	Thread *t;

	a = emalloc(IOCHUNK);
	while((n = read(b->fd, a, IOCHUNK)) > 0){
		m = emalloc(sizeof(Fdmsg)+n);
		m->a = &m[1];
		m->n = n;
		memmove(m->a, a, n);
		lock(&b->lk);
		if(b->m == nil)
			b->em = &b->m;
		*b->em = m;
		b->em = &m->next;
		t = b->t;
		b->t = nil;
		unlock(&b->lk);
		if(t)
			threadready(t);
	}

	lock(&b->lk);
	t = b->t;
	b->dead = 1;
	unlock(&b->lk);
	if(t)
		threadready(t);
}

void
closefdbuf(Fdbuf *b)
{
	Fdmsg *m, *mnext;

	lock(&b->lk);
	while(!b->dead){
		b->t = curthread;
		unlock(&b->lk);
		close(b->fd);
		threadsleep();
		lock(&b->lk);
	}
	for(m=b->m; m; m=mnext){
		mnext = m->next;
		free(m);
	}
	b->m = nil;
	free(b);
}

int
readfdbuf(Fdbuf *b, void *a, int n)
{
	Fdmsg *m;

	lock(&b->lk);
	while(b->m == nil){
		if(b->dead){
			unlock(&b->lk);
			werrstr("connection closed");
			return -1;
		}
		b->t = curthread;
		unlock(&b->lk);
		threadsleep();
		lock(&b->lk);
	}
	m = b->m;
	if(n > m->n)
		n = m->n;
	memmove(a, m->a, n);
	m->a = (uchar*)m->a + n;
	m->n -= n;
	if(m->n == 0){
		b->m = m->next;
		free(m);
	}
	unlock(&b->lk);
	return n;
}

int
readnfdbuf(Fdbuf *b, void *a, int n)
{
	int m;
	uchar *p;

	p = a;
	while(n > 0){
		m = readfdbuf(b, p, n);
		if(m <= 0){
			if(p==a)
				return m;
			break;
		}
		p += m;
		n -= m;
	}
	if(n != 0)
		abort();
	return p-(uchar*)a;
}