forked from cholojuanito/http-proxy
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsbuf.c
143 lines (122 loc) · 3.28 KB
/
sbuf.c
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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
/* $begin sbufc */
#include "csapp.h"
#include "sbuf.h"
/* Create an empty, bounded, shared FIFO buffer with n slots */
/* $begin sbuf_init */
void sbuf_init(sbuf_t *sp, int n)
{
sp->buf = Calloc(n, sizeof(int));
sp->n = n; /* Buffer holds max of n items */
sp->front = sp->rear = 0; /* Empty buffer iff front == rear */
if (sem_init(&sp->mutex, 0, 1) < 0) {
unix_error("sem_init error MUTEX");
}
if (sem_init(&sp->slots, 0, n) < 0) {
unix_error("sem_init error SLOTS");
}
if (sem_init(&sp->items, 0, 0) < 0) {
unix_error("sem_init error ITEMS");
}
}
/* $end sbuf_init */
/* Clean up buffer sp */
/* $begin sbuf_deinit */
void sbuf_deinit(sbuf_t *sp)
{
free(sp->buf);
}
/* $end sbuf_deinit */
/* Insert item onto the rear of shared buffer sp */
/* $begin sbuf_insert */
void sbuf_insert(sbuf_t *sp, int item)
{
if (sem_wait(&sp->slots) < 0) {
unix_error("sem_wait SLOTS error");
}
if (sem_wait(&sp->mutex) < 0) {
unix_error("sem_wait MUTEX error");
}
sp->buf[(++sp->rear)%(sp->n)] = item; // Write to buffer
if (sem_post(&sp->mutex) < 0) {
unix_error("sem_post MUTEX error");
}
if (sem_post(&sp->items) < 0) {
unix_error("sem_post ITEMS error");
}
}
/* $end sbuf_insert */
/* Remove and return the first item from buffer sp */
/* $begin sbuf_remove */
int sbuf_remove(sbuf_t *sp)
{
int item;
if (sem_wait(&sp->items) < 0) {
unix_error("sem_wait ITEMS error");
}
if (sem_wait(&sp->mutex) < 0) {
unix_error("sem_wait MUTEX error");
}
item = sp->buf[(++sp->front)%(sp->n)]; // Remove the item
if (sem_post(&sp->mutex) < 0) {
unix_error("sem_post MUTEX error");
}
if (sem_post(&sp->slots) < 0) {
unix_error("sem_post SLOTS error");
}
return item;
}
/* $end sbuf_remove */
void sbuflog_init(sbuflog_t *sp, int n)
{
sp->buf = Calloc(n, sizeof(char*));
sp->n = n;
sp->front = sp->rear = 0;
if (sem_init(&sp->mutex, 0, 1) < 0) {
unix_error("sem_init error MUTEX");
}
if (sem_init(&sp->slots, 0, n) < 0) {
unix_error("sem_init error SLOTS");
}
if (sem_init(&sp->items, 0, 0) < 0) {
unix_error("sem_init error ITEMS");
}
}
void sbuflog_deinit(sbuflog_t *sp)
{
free(sp->buf);
}
void sbuflog_insert(sbuflog_t *sp, char* item)
{
if (sem_wait(&sp->slots) < 0) {
unix_error("sem_wait SLOTS error");
}
if (sem_wait(&sp->mutex) < 0) {
unix_error("sem_wait MUTEX error");
}
sp->buf[(++sp->rear)%(sp->n)] = item;
if (sem_post(&sp->mutex) < 0) {
unix_error("sem_post MUTEX error");
}
if (sem_post(&sp->items) < 0) {
unix_error("sem_post ITEMS error");
}
}
char* sbuflog_remove(sbuflog_t *sp)
{
char* item;
if (sem_wait(&sp->items) < 0) {
unix_error("sem_wait ITEMS error");
}
if (sem_wait(&sp->mutex) < 0) {
unix_error("sem_wait MUTEX error");
}
item = sp->buf[(++sp->front)%(sp->n)];
if (sem_post(&sp->mutex) < 0) {
unix_error("sem_post MUTEX error");
}
if (sem_post(&sp->slots) < 0) {
unix_error("sem_post SLOTS error");
}
return item;
}
/* $end sbufc */