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"
11 // TODO: expand to all classes
14 /// what kind of I/O the disker needs to do or have done
15 typedef enum { cmdNone
, cmdOpen
, cmdRead
, cmdWrite
} Command
;
17 enum { BufCapacity
= 32*1024 }; // XXX: must not exceed TypedMsgHdr.maxSize
22 /// converts DiskIO requests to IPC messages
23 // TODO: make this IpcIoMsg to make IpcIoRequest and IpcIoResponse similar
28 explicit IpcIoRequest(const Ipc::TypedMsgHdr
& msg
); ///< from recvmsg()
29 void pack(Ipc::TypedMsgHdr
& msg
) const; ///< prepare for sendmsg()
32 int requestorId
; ///< kidId of the requestor; used for response destination
33 unsigned int requestId
; ///< unique for sender; matches request w/ response
35 /* ReadRequest and WriteRequest parameters to pass to disker */
36 char buf
[IpcIo::BufCapacity
]; // XXX: inefficient
40 IpcIo::Command command
; ///< what disker is supposed to do
43 /// disker response to IpcIoRequest
48 explicit IpcIoResponse(const Ipc::TypedMsgHdr
& msg
); ///< from recvmsg()
49 void pack(Ipc::TypedMsgHdr
& msg
) const; ///< prepare for sendmsg()
52 int diskId
; ///< kidId of the responding disker
53 unsigned int requestId
; ///< unique for sender; matches request w/ response
55 char buf
[IpcIo::BufCapacity
]; // XXX: inefficient
58 IpcIo::Command command
; ///< what disker did
60 int xerrno
; ///< I/O error code or zero
63 class IpcIoPendingRequest
;
65 class IpcIoFile
: public DiskFile
69 typedef RefCount
<IpcIoFile
> Pointer
;
71 IpcIoFile(char const *aDb
);
75 virtual void open(int flags
, mode_t mode
, RefCount
<IORequestor
> callback
);
76 virtual void create(int flags
, mode_t mode
, RefCount
<IORequestor
> callback
);
77 virtual void read(ReadRequest
*);
78 virtual void write(WriteRequest
*);
80 virtual bool error() const;
81 virtual int getFD() const;
82 virtual bool canRead() const;
83 virtual bool canWrite() const;
84 virtual bool ioInProgress() const;
86 /// finds and calls the right IpcIoFile upon disker's response
87 static void HandleResponse(const Ipc::TypedMsgHdr
&response
);
89 /// disker entry point for remote I/O requests
90 static void HandleRequest(const IpcIoRequest
&request
);
93 void send(IpcIoRequest
&request
, IpcIoPendingRequest
*pending
);
95 void openCompleted(const IpcIoResponse
&);
96 void readCompleted(ReadRequest
*readRequest
, const IpcIoResponse
&);
97 void writeCompleted(WriteRequest
*writeRequest
, const IpcIoResponse
&);
99 static void RequestTimedOut(void* param
);
100 void requestTimedOut();
101 void removeTimeoutEvent();
102 static IpcIoPendingRequest
*DequeueRequest(unsigned int requestId
);
105 const String dbName
; ///< the name of the file we are managing
106 int diskId
; ///< the process ID of the disker we talk to
107 RefCount
<IORequestor
> ioRequestor
;
109 int ioLevel
; ///< number of pending I/O requests using this file
111 bool error_
; ///< whether we have seen at least one I/O error (XXX)
113 /// maps requestId to the handleResponse callback
114 typedef std::map
<unsigned int, IpcIoPendingRequest
*> RequestsMap
;
115 static RequestsMap TheRequestsMap
; ///< pending requests map
117 static unsigned int LastRequestId
; ///< last requestId used
119 CBDATA_CLASS2(IpcIoFile
);
123 /// keeps original I/O request parameters while disker is handling the request
124 class IpcIoPendingRequest
127 IpcIoPendingRequest(const IpcIoFile::Pointer
&aFile
);
130 IpcIoFile::Pointer file
; ///< the file object waiting for the response
131 ReadRequest
*readRequest
; ///< set if this is a read requests
132 WriteRequest
*writeRequest
; ///< set if this is a write request
135 IpcIoPendingRequest(const IpcIoPendingRequest
&d
); // not implemented
136 IpcIoPendingRequest
&operator =(const IpcIoPendingRequest
&d
); // ditto
140 #endif /* SQUID_IPC_IOFILE_H */