]>
Commit | Line | Data |
---|---|---|
bbc27441 AJ |
1 | /* |
2 | * Copyright (C) 1996-2014 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 | ||
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 | { | |
60 | ||
61 | public: | |
62 | typedef RefCount<IpcIoFile> Pointer; | |
63 | ||
64 | IpcIoFile(char const *aDb); | |
65 | virtual ~IpcIoFile(); | |
66 | ||
67 | /* DiskFile API */ | |
43ebbac3 | 68 | virtual void configure(const Config &cfg); |
254912f3 AR |
69 | virtual void open(int flags, mode_t mode, RefCount<IORequestor> callback); |
70 | virtual void create(int flags, mode_t mode, RefCount<IORequestor> callback); | |
71 | virtual void read(ReadRequest *); | |
72 | virtual void write(WriteRequest *); | |
73 | virtual void close(); | |
74 | virtual bool error() const; | |
75 | virtual int getFD() const; | |
76 | virtual bool canRead() const; | |
77 | virtual bool canWrite() const; | |
78 | virtual bool ioInProgress() const; | |
79 | ||
9a51593d DK |
80 | /// handle open response from coordinator |
81 | static void HandleOpenResponse(const Ipc::StrandSearchResponse &response); | |
254912f3 | 82 | |
9a51593d DK |
83 | /// handle queue push notifications from worker or disker |
84 | static void HandleNotification(const Ipc::TypedMsgHdr &msg); | |
254912f3 | 85 | |
43ebbac3 AR |
86 | DiskFile::Config config; ///< supported configuration options |
87 | ||
caca86d7 AR |
88 | protected: |
89 | friend class IpcIoPendingRequest; | |
9a51593d | 90 | void openCompleted(const Ipc::StrandSearchResponse *const response); |
8ed94021 | 91 | void readCompleted(ReadRequest *readRequest, IpcIoMsg *const response); |
9a51593d | 92 | void writeCompleted(WriteRequest *writeRequest, const IpcIoMsg *const response); |
0a11e039 | 93 | bool canWait() const; |
caca86d7 | 94 | |
254912f3 | 95 | private: |
28bd45ba | 96 | void trackPendingRequest(const unsigned int id, IpcIoPendingRequest *const pending); |
7a907247 | 97 | void push(IpcIoPendingRequest *const pending); |
9a51593d DK |
98 | IpcIoPendingRequest *dequeueRequest(const unsigned int requestId); |
99 | ||
100 | static void Notify(const int peerId); | |
254912f3 | 101 | |
b2aa0934 | 102 | static void OpenTimeout(void *const param); |
9a51593d DK |
103 | static void CheckTimeouts(void *const param); |
104 | void checkTimeouts(); | |
105 | void scheduleTimeoutCheck(); | |
254912f3 | 106 | |
f5591061 | 107 | static void HandleResponses(const char *const when); |
8ed94021 | 108 | void handleResponse(IpcIoMsg &ipcIo); |
9a51593d | 109 | |
3d31b6a5 | 110 | static void DiskerHandleMoreRequests(void*); |
f5591061 | 111 | static void DiskerHandleRequests(); |
9a51593d | 112 | static void DiskerHandleRequest(const int workerId, IpcIoMsg &ipcIo); |
df881a0f | 113 | static bool WaitBeforePop(); |
caca86d7 | 114 | |
254912f3 AR |
115 | private: |
116 | const String dbName; ///< the name of the file we are managing | |
117 | int diskId; ///< the process ID of the disker we talk to | |
118 | RefCount<IORequestor> ioRequestor; | |
119 | ||
254912f3 AR |
120 | bool error_; ///< whether we have seen at least one I/O error (XXX) |
121 | ||
9a51593d DK |
122 | unsigned int lastRequestId; ///< last requestId used |
123 | ||
254912f3 | 124 | /// maps requestId to the handleResponse callback |
caca86d7 | 125 | typedef std::map<unsigned int, IpcIoPendingRequest*> RequestMap; |
9a51593d DK |
126 | RequestMap requestMap1; ///< older (or newer) pending requests |
127 | RequestMap requestMap2; ///< newer (or older) pending requests | |
128 | RequestMap *olderRequests; ///< older requests (map1 or map2) | |
129 | RequestMap *newerRequests; ///< newer requests (map2 or map1) | |
130 | bool timeoutCheckScheduled; ///< we expect a CheckTimeouts() call | |
254912f3 | 131 | |
b2aa0934 DK |
132 | static const double Timeout; ///< timeout value in seconds |
133 | ||
134 | typedef std::list<Pointer> IpcIoFileList; | |
135 | static IpcIoFileList WaitingForOpen; ///< pending open requests | |
136 | ||
137 | ///< maps diskerId to IpcIoFile, cleared in destructor | |
138 | typedef std::map<int, IpcIoFile*> IpcIoFilesMap; | |
139 | static IpcIoFilesMap IpcIoFiles; | |
254912f3 | 140 | |
f5591061 DK |
141 | typedef Ipc::FewToFewBiQueue Queue; |
142 | static std::auto_ptr<Queue> queue; ///< IPC queue | |
143 | ||
3d31b6a5 AR |
144 | /// whether we are waiting for an event to handle still queued I/O requests |
145 | static bool DiskerHandleMoreRequestsScheduled; | |
146 | ||
254912f3 AR |
147 | CBDATA_CLASS2(IpcIoFile); |
148 | }; | |
149 | ||
254912f3 AR |
150 | /// keeps original I/O request parameters while disker is handling the request |
151 | class IpcIoPendingRequest | |
152 | { | |
153 | public: | |
154 | IpcIoPendingRequest(const IpcIoFile::Pointer &aFile); | |
155 | ||
caca86d7 | 156 | /// called when response is received and, with a nil response, on timeouts |
8ed94021 | 157 | void completeIo(IpcIoMsg *const response); |
caca86d7 | 158 | |
254912f3 | 159 | public: |
b2aa0934 | 160 | const IpcIoFile::Pointer file; ///< the file object waiting for the response |
254912f3 AR |
161 | ReadRequest *readRequest; ///< set if this is a read requests |
162 | WriteRequest *writeRequest; ///< set if this is a write request | |
163 | ||
164 | private: | |
165 | IpcIoPendingRequest(const IpcIoPendingRequest &d); // not implemented | |
166 | IpcIoPendingRequest &operator =(const IpcIoPendingRequest &d); // ditto | |
167 | }; | |
168 | ||
254912f3 | 169 | #endif /* SQUID_IPC_IOFILE_H */ |