Add performance patch from #2444, bump release number
[openwrt/svn-archive/archive.git] / net / p910nd / patches / 300-performance.patch
1 --- p910nd-0.7/p910nd.c.orig 2007-09-29 17:03:03.000000000 -0700
2 +++ p910nd-0.7.new/p910nd.c 2007-09-29 17:06:53.000000000 -0700
3 @@ -144,73 +144,185 @@
4 (void)close(lockfd);
5 }
6
7 -ssize_t safe_write(int fd, char *buf, size_t count)
8 +typedef struct {
9 + int detectEof;
10 + int infd;
11 + int outfd;
12 + int startidx;
13 + int endidx;
14 + int bytes;
15 + int totalin;
16 + int totalout;
17 + int eof;
18 + int err;
19 + char buffer[8192];
20 +} Buffer_t;
21 +
22 +void initBuffer( Buffer_t *b, int infd, int outfd, int detectEof )
23 +{
24 + b->detectEof = detectEof;
25 + b->infd = infd;
26 + b->outfd = outfd;
27 + b->startidx = 0;
28 + b->endidx = 0;
29 + b->bytes = 0;
30 + b->totalin = 0;
31 + b->totalout = 0;
32 + b->eof = 0;
33 + b->err = 0;
34 +}
35 +
36 +void prepBuffer( Buffer_t *b, fd_set *readfds, fd_set *writefds )
37 {
38 - size_t offset = 0;
39 -
40 - while (offset < count) {
41 - ssize_t n = write(fd, buf + offset, count - offset);
42 -
43 - if (n < 0 && errno != EINTR)
44 - return n;
45 -
46 - if (n > 0)
47 - offset += n;
48 + if (!b->err && b->bytes != 0) {
49 + FD_SET(b->outfd, writefds);
50 }
51 + if (!b->eof && b->bytes < sizeof(b->buffer)) {
52 + FD_SET(b->infd, readfds);
53 + }
54 +}
55
56 - return offset;
57 +ssize_t readBuffer( Buffer_t *b )
58 +{
59 + int avail;
60 + ssize_t result = 1;
61 + if (b->bytes == 0 || b->err) {
62 + b->startidx = b->endidx = 0;
63 + avail = sizeof(b->buffer);
64 + } else if (b->bytes == sizeof(b->buffer)) {
65 + avail = 0;
66 + } else if (b->endidx > b->startidx) {
67 + avail = sizeof(b->buffer) - b->endidx;
68 + } else {
69 + avail = b->startidx - b->endidx;
70 + }
71 + if (avail) {
72 + result = read(b->infd, b->buffer+b->endidx, avail);
73 + if (result > 0) {
74 + b->endidx += result;
75 + b->totalin += result;
76 + b->bytes += result;
77 + if (b->endidx == sizeof(b->buffer))
78 + b->endidx = 0;
79 + } else if (result < 0 || b->detectEof) {
80 + b->eof = 1;
81 + }
82 + }
83 + return result;
84 +}
85 +
86 +ssize_t writeBuffer( Buffer_t *b )
87 +{
88 + int avail;
89 + ssize_t result = 1;
90 + if (b->bytes == 0 || b->err) {
91 + avail = 0;
92 + } else if (b->endidx > b->startidx) {
93 + avail = b->endidx - b->startidx;
94 + } else {
95 + avail = sizeof(b->buffer) - b->startidx;
96 + }
97 + if (avail) {
98 + result = write(b->outfd, b->buffer + b->startidx, avail);
99 + if (result < 0) {
100 + syslog(LOG_ERR, "write: %m\n");
101 + b->err = 1;
102 + } else {
103 + b->startidx += result;
104 + b->totalout += result;
105 + b->bytes -= result;
106 + if (b->startidx == sizeof(b->buffer))
107 + b->startidx = 0;
108 + }
109 + }
110 + return result;
111 }
112
113 /* Copy network socket to FILE f until EOS */
114 int copy_stream(int fd, int lp)
115 {
116 - int nread, rcvd = 0, sent = 0;
117 - char buffer[8192];
118 + int result;
119 + Buffer_t inbuffer;
120 + initBuffer( &inbuffer, fd, lp, 1 );
121
122 if (bidir) {
123 - for (;;) {
124 - fd_set readfds;
125 - int result;
126 + struct timeval now;
127 + struct timeval then;
128 + struct timeval timeout;
129 + int timer = 0;
130 + Buffer_t outbuffer;
131 + initBuffer ( &outbuffer, lp, fd, 0 );
132 + fd_set readfds;
133 + fd_set writefds;
134 + FD_ZERO(&readfds);
135 + FD_ZERO(&writefds);
136 + FD_SET(lp, &readfds);
137 + FD_SET(fd, &readfds);
138 + while ( (FD_ISSET(fd, &readfds)) ||
139 + (FD_ISSET(lp, &writefds))) {
140 int maxfd = lp > fd ? lp : fd;
141 - FD_ZERO(&readfds);
142 - FD_SET(lp, &readfds);
143 - FD_SET(fd, &readfds);
144 - result = select(maxfd + 1, &readfds, 0, 0, 0);
145 + if (timer) {
146 + gettimeofday(&now,0);
147 + // If timer expired, clear timer
148 + // else don't try reading from printer
149 + if ((now.tv_sec > then.tv_sec) ||
150 + (now.tv_sec == then.tv_sec &&
151 + now.tv_usec > then.tv_usec)) {
152 + timer = 0;
153 + } else {
154 + timeout.tv_sec = then.tv_sec;
155 + timeout.tv_usec = then.tv_usec;
156 + FD_CLR(lp, &readfds);
157 + }
158 + }
159 + if (timer) {
160 + result = select(maxfd + 1, &readfds, &writefds, 0, &timeout);
161 + } else {
162 + result = select(maxfd + 1, &readfds, &writefds, 0, 0);
163 + }
164 if (result < 0)
165 return (result);
166 - if (result == 0)
167 - continue;
168 if (FD_ISSET(fd, &readfds)) {
169 - nread = read(fd, buffer, sizeof(buffer));
170 - if (nread <= 0)
171 - break;
172 - if (safe_write(lp, buffer, nread) < 0) {
173 - syslog(LOG_ERR, "write: %m\n");
174 - break;
175 - }
176 - rcvd += nread;
177 + result = readBuffer(&inbuffer);
178 }
179 if (FD_ISSET(lp, &readfds)) {
180 - nread = read(lp, buffer, sizeof(buffer));
181 - if (nread > 0) {
182 - safe_write(fd, buffer, nread);
183 - sent += nread;
184 + result = readBuffer(&outbuffer);
185 + // Pace the printer data more slowly
186 + if (result >= 0) {
187 + gettimeofday(&then,0);
188 + // wait 100 msec
189 + then.tv_usec += 100000;
190 + if (then.tv_usec > 1000000) {
191 + then.tv_usec -= 1000000;
192 + then.tv_sec ++;
193 + }
194 + timer = 1;
195 }
196 }
197 + if (FD_ISSET(lp, &writefds)) {
198 + result = writeBuffer(&inbuffer);
199 + }
200 + if (FD_ISSET(fd, &writefds)) {
201 + result = writeBuffer(&outbuffer);
202 + /* If socket write error, stop reading from it */
203 + if (result < 0)
204 + inbuffer.eof = 1;
205 + }
206 + FD_ZERO(&readfds);
207 + FD_ZERO(&writefds);
208 + prepBuffer( &inbuffer, &readfds, &writefds );
209 + prepBuffer( &outbuffer, &readfds, &writefds );
210 }
211 syslog(LOG_NOTICE, "Finished job: %d bytes received, %d bytes sent\n",
212 - rcvd, sent);
213 + inbuffer.totalout,
214 + outbuffer.totalout);
215 return (0);
216 } else {
217 - while ((nread = read(fd, buffer, sizeof(buffer))) > 0) {
218 - if (safe_write(lp, buffer, nread) < 0) {
219 - syslog(LOG_ERR, "write: %m\n");
220 - break;
221 - }
222 - rcvd += nread;
223 + while ((result = readBuffer( &inbuffer)) > 0) {
224 + (void)writeBuffer( &inbuffer);
225 }
226 - syslog(LOG_NOTICE, "Finished job: %d bytes received\n", rcvd);
227 - return (nread);
228 + syslog(LOG_NOTICE, "Finished job: %d bytes received\n", inbuffer.totalout);
229 + return (result);
230 }
231 }
232