-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathsocketbuf.h
61 lines (54 loc) · 1.31 KB
/
socketbuf.h
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
#pragma once
#include <cerrno>
#include <iostream>
#include <unistd.h>
#include <boost/fiber/all.hpp>
#include "park_unpark.h"
class Socketbuf : public std::streambuf {
public:
Socketbuf(int fd,ParkSupport& ps) : sockfd(fd), ps(ps) {
setp(buffer, buffer + sizeof(buffer));
}
~Socketbuf() {
close(sockfd);
}
protected:
int underflow() override {
again:
int bytesRead = read(sockfd, buffer, sizeof(buffer));
if (bytesRead <= 0) {
if(errno == EAGAIN || errno == EWOULDBLOCK) {
ps.park();
goto again;
}
return std::char_traits<char>::eof();
}
setg(buffer, buffer, buffer + bytesRead);
return *gptr();
}
int overflow(int c) override {
if (c != EOF) {
*pptr() = c;
pbump(1);
}
return sync() == 0 ? c : EOF;
}
int sync() override {
int len = pptr() - pbase();
again:
int sent = write(sockfd, buffer, len);
if (sent < 0) {
if(errno == EAGAIN || errno == EWOULDBLOCK) {
ps.park();
goto again;
}
return -1;
}
pbump(-len);
return 0;
}
private:
int sockfd;
ParkSupport& ps;
char buffer[4096];
};