1 #ifndef SQUID_IPC_IOFILE_H
2 #define SQUID_IPC_IOFILE_H
4 #include "base/AsyncCall.h"
6 #include "DiskIO/DiskFile.h"
7 #include "DiskIO/IORequestor.h"
8 #include "ipc/forward.h"
9 #include "ipc/mem/Page.h"
15 class FewToFewBiQueue
;
18 // TODO: expand to all classes
21 /// what kind of I/O the disker needs to do or have done
22 typedef enum { cmdNone
, cmdOpen
, cmdRead
, cmdWrite
} Command
;
27 /// converts DiskIO requests to IPC queue messages
33 unsigned int requestId
; ///< unique for requestor; matches request w/ response
37 Ipc::Mem::PageId page
;
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
42 int xerrno
; ///< I/O error code or zero
45 class IpcIoPendingRequest
;
47 class IpcIoFile
: public DiskFile
51 typedef RefCount
<IpcIoFile
> Pointer
;
53 IpcIoFile(char const *aDb
);
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
*);
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;
68 /// handle open response from coordinator
69 static void HandleOpenResponse(const Ipc::StrandSearchResponse
&response
);
71 /// handle queue push notifications from worker or disker
72 static void HandleNotification(const Ipc::TypedMsgHdr
&msg
);
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
);
82 void trackPendingRequest(IpcIoPendingRequest
*const pending
);
83 void push(IpcIoPendingRequest
*const pending
);
84 IpcIoPendingRequest
*dequeueRequest(const unsigned int requestId
);
86 static void Notify(const int peerId
);
88 static void OpenTimeout(void *const param
);
89 static void CheckTimeouts(void *const param
);
91 void scheduleTimeoutCheck();
93 static void HandleResponses(const char *const when
);
94 void handleResponse(IpcIoMsg
&ipcIo
);
96 static void DiskerHandleMoreRequests(void*);
97 static void DiskerHandleRequests();
98 static void DiskerHandleRequest(const int workerId
, IpcIoMsg
&ipcIo
);
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
;
105 bool error_
; ///< whether we have seen at least one I/O error (XXX)
107 unsigned int lastRequestId
; ///< last requestId used
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
117 static const double Timeout
; ///< timeout value in seconds
119 typedef std::list
<Pointer
> IpcIoFileList
;
120 static IpcIoFileList WaitingForOpen
; ///< pending open requests
122 ///< maps diskerId to IpcIoFile, cleared in destructor
123 typedef std::map
<int, IpcIoFile
*> IpcIoFilesMap
;
124 static IpcIoFilesMap IpcIoFiles
;
126 typedef Ipc::FewToFewBiQueue Queue
;
127 static std::auto_ptr
<Queue
> queue
; ///< IPC queue
129 /// whether we are waiting for an event to handle still queued I/O requests
130 static bool DiskerHandleMoreRequestsScheduled
;
132 CBDATA_CLASS2(IpcIoFile
);
136 /// keeps original I/O request parameters while disker is handling the request
137 class IpcIoPendingRequest
140 IpcIoPendingRequest(const IpcIoFile::Pointer
&aFile
);
142 /// called when response is received and, with a nil response, on timeouts
143 void completeIo(IpcIoMsg
*const response
);
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
151 IpcIoPendingRequest(const IpcIoPendingRequest
&d
); // not implemented
152 IpcIoPendingRequest
&operator =(const IpcIoPendingRequest
&d
); // ditto
156 #endif /* SQUID_IPC_IOFILE_H */