]> git.ipfire.org Git - thirdparty/squid.git/blob - src/DiskIO/IpcIo/IpcIoFile.h
Source Format Enforcement (#763)
[thirdparty/squid.git] / src / DiskIO / IpcIo / IpcIoFile.h
1 /*
2 * Copyright (C) 1996-2021 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 std::ostream &operator <<(std::ostream &, IpcIo::Command);
38
39 /// converts DiskIO requests to IPC queue messages
40 class IpcIoMsg
41 {
42 public:
43 IpcIoMsg();
44
45 /// prints message parameters; suitable for cache manager reports
46 void stat(std::ostream &);
47
48 public:
49 unsigned int requestId; ///< unique for requestor; matches request w/ response
50
51 off_t offset;
52 size_t len;
53 Ipc::Mem::PageId page;
54 pid_t workerPid; ///< the process ID of the I/O requestor
55
56 IpcIo::Command command; ///< what disker is supposed to do or did
57 struct timeval start; ///< when the I/O request was converted to IpcIoMsg
58
59 int xerrno; ///< I/O error code or zero
60 };
61
62 class IpcIoPendingRequest;
63
64 /// In a worker process, represents a single (remote) cache_dir disker file.
65 /// In a disker process, used as a bunch of static methods handling that file.
66 class IpcIoFile: public DiskFile
67 {
68 CBDATA_CLASS(IpcIoFile);
69
70 public:
71 typedef RefCount<IpcIoFile> Pointer;
72
73 IpcIoFile(char const *aDb);
74 virtual ~IpcIoFile();
75
76 /* DiskFile API */
77 virtual void configure(const Config &cfg);
78 virtual void open(int flags, mode_t mode, RefCount<IORequestor> callback);
79 virtual void create(int flags, mode_t mode, RefCount<IORequestor> callback);
80 virtual void read(ReadRequest *);
81 virtual void write(WriteRequest *);
82 virtual void close();
83 virtual bool error() const;
84 virtual int getFD() const;
85 virtual bool canRead() const;
86 virtual bool canWrite() const;
87 virtual bool ioInProgress() const;
88
89 /// handle open response from coordinator
90 static void HandleOpenResponse(const Ipc::StrandMessage &);
91
92 /// handle queue push notifications from worker or disker
93 static void HandleNotification(const Ipc::TypedMsgHdr &msg);
94
95 /// prints IPC message queue state; suitable for cache manager reports
96 static void StatQueue(std::ostream &);
97
98 DiskFile::Config config; ///< supported configuration options
99
100 protected:
101 friend class IpcIoPendingRequest;
102 void openCompleted(const Ipc::StrandMessage *);
103 void readCompleted(ReadRequest *readRequest, IpcIoMsg *const response);
104 void writeCompleted(WriteRequest *writeRequest, const IpcIoMsg *const response);
105 bool canWait() const;
106
107 private:
108 void trackPendingRequest(const unsigned int id, IpcIoPendingRequest *const pending);
109 void push(IpcIoPendingRequest *const pending);
110 IpcIoPendingRequest *dequeueRequest(const unsigned int requestId);
111
112 /// the total number of I/O requests in push queue and pop queue
113 /// (but no, the implementation does not add push and pop queue sizes)
114 size_t pendingRequests() const { return olderRequests->size() + newerRequests->size(); }
115
116 static void Notify(const int peerId);
117
118 static void OpenTimeout(void *const param);
119 static void CheckTimeouts(void *const param);
120 void checkTimeouts();
121 void scheduleTimeoutCheck();
122
123 static void HandleResponses(const char *const when);
124 void handleResponse(IpcIoMsg &ipcIo);
125
126 static void DiskerHandleMoreRequests(void*);
127 static void DiskerHandleRequests();
128 static void DiskerHandleRequest(const int workerId, IpcIoMsg &ipcIo);
129 static bool WaitBeforePop();
130
131 private:
132 const String dbName; ///< the name of the file we are managing
133 const pid_t myPid; ///< optimization: cached process ID of our process
134 int diskId; ///< the kid ID of the disker we talk to
135 RefCount<IORequestor> ioRequestor;
136
137 bool error_; ///< whether we have seen at least one I/O error (XXX)
138
139 unsigned int lastRequestId; ///< last requestId used
140
141 /// maps requestId to the handleResponse callback
142 typedef std::map<unsigned int, IpcIoPendingRequest*> RequestMap;
143 RequestMap requestMap1; ///< older (or newer) pending requests
144 RequestMap requestMap2; ///< newer (or older) pending requests
145 RequestMap *olderRequests; ///< older requests (map1 or map2)
146 RequestMap *newerRequests; ///< newer requests (map2 or map1)
147 bool timeoutCheckScheduled; ///< we expect a CheckTimeouts() call
148
149 static const double Timeout; ///< timeout value in seconds
150
151 typedef std::list<Pointer> IpcIoFileList;
152 static IpcIoFileList WaitingForOpen; ///< pending open requests
153
154 ///< maps diskerId to IpcIoFile, cleared in destructor
155 typedef std::map<int, IpcIoFile*> IpcIoFilesMap;
156 static IpcIoFilesMap IpcIoFiles;
157
158 typedef Ipc::FewToFewBiQueue Queue;
159 static std::unique_ptr<Queue> queue; ///< IPC queue
160
161 /// whether we are waiting for an event to handle still queued I/O requests
162 static bool DiskerHandleMoreRequestsScheduled;
163 };
164
165 /// keeps original I/O request parameters while disker is handling the request
166 class IpcIoPendingRequest
167 {
168 public:
169 IpcIoPendingRequest(const IpcIoFile::Pointer &aFile);
170
171 /// called when response is received and, with a nil response, on timeouts
172 void completeIo(IpcIoMsg *const response);
173
174 public:
175 const IpcIoFile::Pointer file; ///< the file object waiting for the response
176 ReadRequest *readRequest; ///< set if this is a read requests
177 WriteRequest *writeRequest; ///< set if this is a write request
178
179 CodeContext::Pointer codeContext; ///< requestor's context
180
181 private:
182 IpcIoPendingRequest(const IpcIoPendingRequest &d); // not implemented
183 IpcIoPendingRequest &operator =(const IpcIoPendingRequest &d); // ditto
184 };
185
186 #endif /* SQUID_IPC_IOFILE_H */
187