]> git.ipfire.org Git - thirdparty/squid.git/blob - src/DiskIO/IpcIo/IpcIoFile.h
Merge 3p2-rock.
[thirdparty/squid.git] / src / DiskIO / IpcIo / IpcIoFile.h
1 #ifndef SQUID_IPC_IOFILE_H
2 #define SQUID_IPC_IOFILE_H
3
4 #include "base/AsyncCall.h"
5 #include "cbdata.h"
6 #include "DiskIO/DiskFile.h"
7 #include "DiskIO/IORequestor.h"
8 #include "ipc/forward.h"
9 #include <map>
10
11 // TODO: expand to all classes
12 namespace IpcIo {
13
14 /// what kind of I/O the disker needs to do or have done
15 typedef enum { cmdNone, cmdOpen, cmdRead, cmdWrite } Command;
16
17 enum { BufCapacity = 32*1024 }; // XXX: must not exceed TypedMsgHdr.maxSize
18
19 } // namespace IpcIo
20
21
22 /// converts DiskIO requests to IPC messages
23 // TODO: make this IpcIoMsg to make IpcIoRequest and IpcIoResponse similar
24 class IpcIoRequest {
25 public:
26 IpcIoRequest();
27
28 explicit IpcIoRequest(const Ipc::TypedMsgHdr& msg); ///< from recvmsg()
29 void pack(Ipc::TypedMsgHdr& msg) const; ///< prepare for sendmsg()
30
31 public:
32 int requestorId; ///< kidId of the requestor; used for response destination
33 unsigned int requestId; ///< unique for sender; matches request w/ response
34
35 /* ReadRequest and WriteRequest parameters to pass to disker */
36 char buf[IpcIo::BufCapacity]; // XXX: inefficient
37 off_t offset;
38 size_t len;
39
40 IpcIo::Command command; ///< what disker is supposed to do
41 };
42
43 /// disker response to IpcIoRequest
44 class IpcIoResponse {
45 public:
46 IpcIoResponse();
47
48 explicit IpcIoResponse(const Ipc::TypedMsgHdr& msg); ///< from recvmsg()
49 void pack(Ipc::TypedMsgHdr& msg) const; ///< prepare for sendmsg()
50
51 public:
52 int diskId; ///< kidId of the responding disker
53 unsigned int requestId; ///< unique for sender; matches request w/ response
54
55 char buf[IpcIo::BufCapacity]; // XXX: inefficient
56 size_t len;
57
58 IpcIo::Command command; ///< what disker did
59
60 int xerrno; ///< I/O error code or zero
61 };
62
63 class IpcIoPendingRequest;
64
65 class IpcIoFile: public DiskFile
66 {
67
68 public:
69 typedef RefCount<IpcIoFile> Pointer;
70
71 IpcIoFile(char const *aDb);
72 virtual ~IpcIoFile();
73
74 /* DiskFile API */
75 virtual void open(int flags, mode_t mode, RefCount<IORequestor> callback);
76 virtual void create(int flags, mode_t mode, RefCount<IORequestor> callback);
77 virtual void read(ReadRequest *);
78 virtual void write(WriteRequest *);
79 virtual void close();
80 virtual bool error() const;
81 virtual int getFD() const;
82 virtual bool canRead() const;
83 virtual bool canWrite() const;
84 virtual bool ioInProgress() const;
85
86 /// finds and calls the right IpcIoFile upon disker's response
87 static void HandleResponse(const Ipc::TypedMsgHdr &response);
88
89 /// disker entry point for remote I/O requests
90 static void HandleRequest(const IpcIoRequest &request);
91
92 private:
93 void send(IpcIoRequest &request, IpcIoPendingRequest *pending);
94
95 void openCompleted(const IpcIoResponse &);
96 void readCompleted(ReadRequest *readRequest, const IpcIoResponse &);
97 void writeCompleted(WriteRequest *writeRequest, const IpcIoResponse &);
98
99 static void RequestTimedOut(void* param);
100 void requestTimedOut();
101 void removeTimeoutEvent();
102 static IpcIoPendingRequest *DequeueRequest(unsigned int requestId);
103
104 private:
105 const String dbName; ///< the name of the file we are managing
106 int diskId; ///< the process ID of the disker we talk to
107 RefCount<IORequestor> ioRequestor;
108
109 int ioLevel; ///< number of pending I/O requests using this file
110
111 bool error_; ///< whether we have seen at least one I/O error (XXX)
112
113 /// maps requestId to the handleResponse callback
114 typedef std::map<unsigned int, IpcIoPendingRequest*> RequestsMap;
115 static RequestsMap TheRequestsMap; ///< pending requests map
116
117 static unsigned int LastRequestId; ///< last requestId used
118
119 CBDATA_CLASS2(IpcIoFile);
120 };
121
122
123 /// keeps original I/O request parameters while disker is handling the request
124 class IpcIoPendingRequest
125 {
126 public:
127 IpcIoPendingRequest(const IpcIoFile::Pointer &aFile);
128
129 public:
130 IpcIoFile::Pointer file; ///< the file object waiting for the response
131 ReadRequest *readRequest; ///< set if this is a read requests
132 WriteRequest *writeRequest; ///< set if this is a write request
133
134 private:
135 IpcIoPendingRequest(const IpcIoPendingRequest &d); // not implemented
136 IpcIoPendingRequest &operator =(const IpcIoPendingRequest &d); // ditto
137 };
138
139
140 #endif /* SQUID_IPC_IOFILE_H */