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"
13 // TODO: expand to all classes
16 /// what kind of I/O the disker needs to do or have done
17 typedef enum { cmdNone
, cmdOpen
, cmdRead
, cmdWrite
} Command
;
19 enum { BufCapacity
= 32*1024 }; // XXX: must not exceed TypedMsgHdr.maxSize
24 /// converts DiskIO requests to IPC queue messages
30 unsigned int requestId
; ///< unique for requestor; matches request w/ response
32 char buf
[IpcIo::BufCapacity
]; // XXX: inefficient
36 IpcIo::Command command
; ///< what disker is supposed to do or did
38 int xerrno
; ///< I/O error code or zero
41 class IpcIoPendingRequest
;
43 class IpcIoFile
: public DiskFile
47 typedef RefCount
<IpcIoFile
> Pointer
;
49 IpcIoFile(char const *aDb
);
53 virtual void open(int flags
, mode_t mode
, RefCount
<IORequestor
> callback
);
54 virtual void create(int flags
, mode_t mode
, RefCount
<IORequestor
> callback
);
55 virtual void read(ReadRequest
*);
56 virtual void write(WriteRequest
*);
58 virtual bool error() const;
59 virtual int getFD() const;
60 virtual bool canRead() const;
61 virtual bool canWrite() const;
62 virtual bool ioInProgress() const;
64 /// handle open response from coordinator
65 static void HandleOpenResponse(const Ipc::StrandSearchResponse
&response
);
67 /// handle queue push notifications from worker or disker
68 static void HandleNotification(const Ipc::TypedMsgHdr
&msg
);
71 friend class IpcIoPendingRequest
;
72 void openCompleted(const Ipc::StrandSearchResponse
*const response
);
73 void readCompleted(ReadRequest
*readRequest
, const IpcIoMsg
*const response
);
74 void writeCompleted(WriteRequest
*writeRequest
, const IpcIoMsg
*const response
);
77 void trackPendingRequest(IpcIoPendingRequest
*const pending
);
78 void push(IpcIoPendingRequest
*const pending
);
79 IpcIoPendingRequest
*dequeueRequest(const unsigned int requestId
);
81 static void Notify(const int peerId
);
83 static void OpenTimeout(void *const param
);
84 static void CheckTimeouts(void *const param
);
86 void scheduleTimeoutCheck();
88 void handleNotification();
89 void handleResponses(const char *when
);
90 void handleResponse(const IpcIoMsg
&ipcIo
);
92 static void DiskerHandleRequests(const int workerId
);
93 static void DiskerHandleRequest(const int workerId
, IpcIoMsg
&ipcIo
);
96 typedef FewToOneBiQueue DiskerQueue
;
97 typedef OneToOneBiQueue WorkerQueue
;
99 const String dbName
; ///< the name of the file we are managing
100 int diskId
; ///< the process ID of the disker we talk to
101 static DiskerQueue
*diskerQueue
; ///< IPC queue for disker
102 WorkerQueue
*workerQueue
; ///< IPC queue for worker
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 CBDATA_CLASS2(IpcIoFile
);
130 /// keeps original I/O request parameters while disker is handling the request
131 class IpcIoPendingRequest
134 IpcIoPendingRequest(const IpcIoFile::Pointer
&aFile
);
136 /// called when response is received and, with a nil response, on timeouts
137 void completeIo(const IpcIoMsg
*const response
);
140 const IpcIoFile::Pointer file
; ///< the file object waiting for the response
141 ReadRequest
*readRequest
; ///< set if this is a read requests
142 WriteRequest
*writeRequest
; ///< set if this is a write request
145 IpcIoPendingRequest(const IpcIoPendingRequest
&d
); // not implemented
146 IpcIoPendingRequest
&operator =(const IpcIoPendingRequest
&d
); // ditto
150 #endif /* SQUID_IPC_IOFILE_H */