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