]>
Commit | Line | Data |
---|---|---|
bbc27441 | 1 | /* |
4ac4a490 | 2 | * Copyright (C) 1996-2017 The Squid Software Foundation and contributors |
bbc27441 AJ |
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 | ||
254912f3 AR |
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" | |
8ed94021 | 17 | #include "ipc/mem/Page.h" |
602d9612 | 18 | #include "SquidString.h" |
b2aa0934 | 19 | #include <list> |
254912f3 | 20 | #include <map> |
f5591061 DK |
21 | #include <memory> |
22 | ||
9199139f AR |
23 | namespace Ipc |
24 | { | |
f5591061 DK |
25 | class FewToFewBiQueue; |
26 | } // Ipc | |
254912f3 AR |
27 | |
28 | // TODO: expand to all classes | |
9199139f AR |
29 | namespace IpcIo |
30 | { | |
254912f3 AR |
31 | |
32 | /// what kind of I/O the disker needs to do or have done | |
33 | typedef enum { cmdNone, cmdOpen, cmdRead, cmdWrite } Command; | |
34 | ||
254912f3 AR |
35 | } // namespace IpcIo |
36 | ||
9a51593d | 37 | /// converts DiskIO requests to IPC queue messages |
9199139f AR |
38 | class IpcIoMsg |
39 | { | |
254912f3 | 40 | public: |
9a51593d | 41 | IpcIoMsg(); |
254912f3 AR |
42 | |
43 | public: | |
9a51593d | 44 | unsigned int requestId; ///< unique for requestor; matches request w/ response |
254912f3 | 45 | |
254912f3 AR |
46 | off_t offset; |
47 | size_t len; | |
8ed94021 | 48 | Ipc::Mem::PageId page; |
254912f3 | 49 | |
9a51593d | 50 | IpcIo::Command command; ///< what disker is supposed to do or did |
0a11e039 | 51 | struct timeval start; ///< when the I/O request was converted to IpcIoMsg |
254912f3 AR |
52 | |
53 | int xerrno; ///< I/O error code or zero | |
54 | }; | |
55 | ||
56 | class IpcIoPendingRequest; | |
57 | ||
58 | class IpcIoFile: public DiskFile | |
59 | { | |
5c2f68b7 | 60 | CBDATA_CLASS(IpcIoFile); |
254912f3 AR |
61 | |
62 | public: | |
63 | typedef RefCount<IpcIoFile> Pointer; | |
64 | ||
65 | IpcIoFile(char const *aDb); | |
66 | virtual ~IpcIoFile(); | |
67 | ||
68 | /* DiskFile API */ | |
43ebbac3 | 69 | virtual void configure(const Config &cfg); |
254912f3 AR |
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 | ||
9a51593d DK |
81 | /// handle open response from coordinator |
82 | static void HandleOpenResponse(const Ipc::StrandSearchResponse &response); | |
254912f3 | 83 | |
9a51593d DK |
84 | /// handle queue push notifications from worker or disker |
85 | static void HandleNotification(const Ipc::TypedMsgHdr &msg); | |
254912f3 | 86 | |
43ebbac3 AR |
87 | DiskFile::Config config; ///< supported configuration options |
88 | ||
caca86d7 AR |
89 | protected: |
90 | friend class IpcIoPendingRequest; | |
9a51593d | 91 | void openCompleted(const Ipc::StrandSearchResponse *const response); |
8ed94021 | 92 | void readCompleted(ReadRequest *readRequest, IpcIoMsg *const response); |
9a51593d | 93 | void writeCompleted(WriteRequest *writeRequest, const IpcIoMsg *const response); |
0a11e039 | 94 | bool canWait() const; |
caca86d7 | 95 | |
254912f3 | 96 | private: |
28bd45ba | 97 | void trackPendingRequest(const unsigned int id, IpcIoPendingRequest *const pending); |
7a907247 | 98 | void push(IpcIoPendingRequest *const pending); |
9a51593d DK |
99 | IpcIoPendingRequest *dequeueRequest(const unsigned int requestId); |
100 | ||
101 | static void Notify(const int peerId); | |
254912f3 | 102 | |
b2aa0934 | 103 | static void OpenTimeout(void *const param); |
9a51593d DK |
104 | static void CheckTimeouts(void *const param); |
105 | void checkTimeouts(); | |
106 | void scheduleTimeoutCheck(); | |
254912f3 | 107 | |
f5591061 | 108 | static void HandleResponses(const char *const when); |
8ed94021 | 109 | void handleResponse(IpcIoMsg &ipcIo); |
9a51593d | 110 | |
3d31b6a5 | 111 | static void DiskerHandleMoreRequests(void*); |
f5591061 | 112 | static void DiskerHandleRequests(); |
9a51593d | 113 | static void DiskerHandleRequest(const int workerId, IpcIoMsg &ipcIo); |
df881a0f | 114 | static bool WaitBeforePop(); |
caca86d7 | 115 | |
254912f3 AR |
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 | ||
254912f3 AR |
121 | bool error_; ///< whether we have seen at least one I/O error (XXX) |
122 | ||
9a51593d DK |
123 | unsigned int lastRequestId; ///< last requestId used |
124 | ||
254912f3 | 125 | /// maps requestId to the handleResponse callback |
caca86d7 | 126 | typedef std::map<unsigned int, IpcIoPendingRequest*> RequestMap; |
9a51593d DK |
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 | |
254912f3 | 132 | |
b2aa0934 DK |
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; | |
254912f3 | 141 | |
f5591061 | 142 | typedef Ipc::FewToFewBiQueue Queue; |
829030b5 | 143 | static std::unique_ptr<Queue> queue; ///< IPC queue |
f5591061 | 144 | |
3d31b6a5 AR |
145 | /// whether we are waiting for an event to handle still queued I/O requests |
146 | static bool DiskerHandleMoreRequestsScheduled; | |
254912f3 AR |
147 | }; |
148 | ||
254912f3 AR |
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 | ||
caca86d7 | 155 | /// called when response is received and, with a nil response, on timeouts |
8ed94021 | 156 | void completeIo(IpcIoMsg *const response); |
caca86d7 | 157 | |
254912f3 | 158 | public: |
b2aa0934 | 159 | const IpcIoFile::Pointer file; ///< the file object waiting for the response |
254912f3 AR |
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 | ||
254912f3 | 168 | #endif /* SQUID_IPC_IOFILE_H */ |
f53969cc | 169 |