00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef TRANSCEIVER_HPP
00023 #define TRANSCEIVER_HPP
00024
00025 #include <map>
00026 #include <list>
00027 #include <queue>
00028 #include <algorithm>
00029 #include <map>
00030
00031 #include <boost/function.hpp>
00032 #include <boost/bind.hpp>
00033 #include <boost/shared_array.hpp>
00034
00035 #include <unistd.h>
00036 #include <fcntl.h>
00037 #include <errno.h>
00038 #include <sys/epoll.h>
00039 #include <sys/socket.h>
00040 #include <sys/un.h>
00041 #include <signal.h>
00042
00043 #include <fastcgi++/protocol.hpp>
00044 #include <fastcgi++/exceptions.hpp>
00045
00047 namespace Fastcgipp
00048 {
00050
00054 struct Block
00055 {
00057
00061 Block(char* data_, size_t size_): data(data_), size(size_) { }
00063 Block(const Block& block): data(block.data), size(block.size) { }
00065 const Block& operator=(const Block& block) { data=block.data; size=block.size; }
00067 char* data;
00069 size_t size;
00070 };
00071
00073
00077 class Transceiver
00078 {
00079 public:
00081
00088 bool handler();
00089
00091 Block requestWrite(size_t size) { return buffer.requestWrite(size); }
00093 void secureWrite(size_t size, Protocol::FullId id, bool kill) { buffer.secureWrite(size, id, kill); transmit(); }
00095
00102 Transceiver(int fd_, boost::function<void(Protocol::FullId, Message)> sendMessage_);
00104 void sleep();
00105
00106 private:
00108 struct fdBuffer
00109 {
00111 Protocol::Header headerBuffer;
00113 Message messageBuffer;
00114 };
00115
00117
00127 class Buffer
00128 {
00130 struct Frame
00131 {
00133
00138 Frame(size_t size_, bool closeFd_, Protocol::FullId id_): size(size_), closeFd(closeFd_), id(id_) { }
00140 size_t size;
00142 bool closeFd;
00144 Protocol::FullId id;
00145 };
00147 std::queue<Frame> frames;
00149 const static unsigned int minBlockSize = 256;
00151 struct Chunk
00152 {
00154 const static unsigned int size = 131072;
00156 boost::shared_array<char> data;
00158 char* end;
00160 Chunk(): data(new char[size]), end(data.get()) { }
00161 ~Chunk() { }
00163 Chunk(const Chunk& chunk): data(chunk.data), end(data.get()) { }
00164 };
00165
00167 std::list<Chunk> chunks;
00169 std::list<Chunk>::iterator writeIt;
00170
00172 char* pRead;
00173
00175 int& epollFd;
00177 std::map<int, fdBuffer>& fdBuffers;
00178 public:
00180
00184 Buffer(int& epollFd_, std::map<int, fdBuffer>& fdBuffers_): epollFd(epollFd_), fdBuffers(fdBuffers_), chunks(1), pRead(chunks.begin()->data.get()), writeIt(chunks.begin()) { }
00185
00187
00191 Block requestWrite(size_t size)
00192 {
00193 return Block(writeIt->end, std::min(size, (size_t)(writeIt->data.get()+Chunk::size-writeIt->end)));
00194 }
00196
00201 void secureWrite(size_t size, Protocol::FullId id, bool kill);
00202
00204 struct SendBlock
00205 {
00207
00212 SendBlock(const char* data_, size_t size_, int fd_): data(data_), size(size_), fd(fd_) { }
00214 SendBlock(const SendBlock& sendBlock): data(sendBlock.data), size(sendBlock.size), fd(sendBlock.fd) { }
00216 const char* data;
00218 size_t size;
00220 int fd;
00221 };
00222
00224
00227 SendBlock requestRead()
00228 {
00229 return SendBlock(pRead, frames.empty()?0:frames.front().size, frames.empty()?-1:frames.front().id.fd);
00230 }
00232
00235 void freeRead(size_t size);
00236
00238
00241 bool empty()
00242 {
00243 return pRead==writeIt->end;
00244 }
00245 };
00246
00248 Buffer buffer;
00250 boost::function<void(Protocol::FullId, Message)> sendMessage;
00252 int socket;
00254 int epollFd;
00256 std::map<int, fdBuffer> fdBuffers;
00258 int transmit();
00259 };
00260 }
00261
00262 #endif