]> git.ipfire.org Git - thirdparty/squid.git/blob - src/DiskIO/IpcIo/IpcIoFile.h
Merged from parent (trunk r11700, v3.2.0.11+).
[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 "ipc/mem/Page.h"
10 #include <list>
11 #include <map>
12 #include <memory>
13
14 namespace Ipc {
15 class FewToFewBiQueue;
16 } // Ipc
17
18 // TODO: expand to all classes
19 namespace IpcIo {
20
21 /// what kind of I/O the disker needs to do or have done
22 typedef enum { cmdNone, cmdOpen, cmdRead, cmdWrite } Command;
23
24 } // namespace IpcIo
25
26
27 /// converts DiskIO requests to IPC queue messages
28 class IpcIoMsg {
29 public:
30 IpcIoMsg();
31
32 public:
33 unsigned int requestId; ///< unique for requestor; matches request w/ response
34
35 off_t offset;
36 size_t len;
37 Ipc::Mem::PageId page;
38
39 IpcIo::Command command; ///< what disker is supposed to do or did
40 struct timeval start; ///< when the I/O request was converted to IpcIoMsg
41
42 int xerrno; ///< I/O error code or zero
43 };
44
45 class IpcIoPendingRequest;
46
47 class IpcIoFile: public DiskFile
48 {
49
50 public:
51 typedef RefCount<IpcIoFile> Pointer;
52
53 IpcIoFile(char const *aDb);
54 virtual ~IpcIoFile();
55
56 /* DiskFile API */
57 virtual void open(int flags, mode_t mode, RefCount<IORequestor> callback);
58 virtual void create(int flags, mode_t mode, RefCount<IORequestor> callback);
59 virtual void read(ReadRequest *);
60 virtual void write(WriteRequest *);
61 virtual void close();
62 virtual bool error() const;
63 virtual int getFD() const;
64 virtual bool canRead() const;
65 virtual bool canWrite() const;
66 virtual bool ioInProgress() const;
67
68 /// handle open response from coordinator
69 static void HandleOpenResponse(const Ipc::StrandSearchResponse &response);
70
71 /// handle queue push notifications from worker or disker
72 static void HandleNotification(const Ipc::TypedMsgHdr &msg);
73
74 protected:
75 friend class IpcIoPendingRequest;
76 void openCompleted(const Ipc::StrandSearchResponse *const response);
77 void readCompleted(ReadRequest *readRequest, IpcIoMsg *const response);
78 void writeCompleted(WriteRequest *writeRequest, const IpcIoMsg *const response);
79 bool canWait() const;
80
81 private:
82 void trackPendingRequest(IpcIoPendingRequest *const pending);
83 void push(IpcIoPendingRequest *const pending);
84 IpcIoPendingRequest *dequeueRequest(const unsigned int requestId);
85
86 static void Notify(const int peerId);
87
88 static void OpenTimeout(void *const param);
89 static void CheckTimeouts(void *const param);
90 void checkTimeouts();
91 void scheduleTimeoutCheck();
92
93 static void HandleResponses(const char *const when);
94 void handleResponse(IpcIoMsg &ipcIo);
95
96 static void DiskerHandleMoreRequests(void*);
97 static void DiskerHandleRequests();
98 static void DiskerHandleRequest(const int workerId, IpcIoMsg &ipcIo);
99
100 private:
101 const String dbName; ///< the name of the file we are managing
102 int diskId; ///< the process ID of the disker we talk to
103 RefCount<IORequestor> ioRequestor;
104
105 bool error_; ///< whether we have seen at least one I/O error (XXX)
106
107 unsigned int lastRequestId; ///< last requestId used
108
109 /// maps requestId to the handleResponse callback
110 typedef std::map<unsigned int, IpcIoPendingRequest*> RequestMap;
111 RequestMap requestMap1; ///< older (or newer) pending requests
112 RequestMap requestMap2; ///< newer (or older) pending requests
113 RequestMap *olderRequests; ///< older requests (map1 or map2)
114 RequestMap *newerRequests; ///< newer requests (map2 or map1)
115 bool timeoutCheckScheduled; ///< we expect a CheckTimeouts() call
116
117 static const double Timeout; ///< timeout value in seconds
118
119 typedef std::list<Pointer> IpcIoFileList;
120 static IpcIoFileList WaitingForOpen; ///< pending open requests
121
122 ///< maps diskerId to IpcIoFile, cleared in destructor
123 typedef std::map<int, IpcIoFile*> IpcIoFilesMap;
124 static IpcIoFilesMap IpcIoFiles;
125
126 typedef Ipc::FewToFewBiQueue Queue;
127 static std::auto_ptr<Queue> queue; ///< IPC queue
128
129 /// whether we are waiting for an event to handle still queued I/O requests
130 static bool DiskerHandleMoreRequestsScheduled;
131
132 CBDATA_CLASS2(IpcIoFile);
133 };
134
135
136 /// keeps original I/O request parameters while disker is handling the request
137 class IpcIoPendingRequest
138 {
139 public:
140 IpcIoPendingRequest(const IpcIoFile::Pointer &aFile);
141
142 /// called when response is received and, with a nil response, on timeouts
143 void completeIo(IpcIoMsg *const response);
144
145 public:
146 const IpcIoFile::Pointer file; ///< the file object waiting for the response
147 ReadRequest *readRequest; ///< set if this is a read requests
148 WriteRequest *writeRequest; ///< set if this is a write request
149
150 private:
151 IpcIoPendingRequest(const IpcIoPendingRequest &d); // not implemented
152 IpcIoPendingRequest &operator =(const IpcIoPendingRequest &d); // ditto
153 };
154
155
156 #endif /* SQUID_IPC_IOFILE_H */