+/*
+ * Copyright (C) 1996-2018 The Squid Software Foundation and contributors
+ *
+ * Squid software is distributed under GPLv2+ license and includes
+ * contributions from numerous individuals and organizations.
+ * Please see the COPYING and CONTRIBUTORS files for details.
+ */
+
#ifndef SQUID_IPC_IOFILE_H
#define SQUID_IPC_IOFILE_H
#include "DiskIO/DiskFile.h"
#include "DiskIO/IORequestor.h"
#include "ipc/forward.h"
-#include "ipc/Queue.h"
+#include "ipc/mem/Page.h"
+#include "SquidString.h"
#include <list>
#include <map>
+#include <memory>
+
+namespace Ipc
+{
+class FewToFewBiQueue;
+} // Ipc
// TODO: expand to all classes
-namespace IpcIo {
+namespace IpcIo
+{
/// what kind of I/O the disker needs to do or have done
typedef enum { cmdNone, cmdOpen, cmdRead, cmdWrite } Command;
-enum { BufCapacity = 32*1024 }; // XXX: must not exceed TypedMsgHdr.maxSize
-
} // namespace IpcIo
-
/// converts DiskIO requests to IPC queue messages
-class IpcIoMsg {
+class IpcIoMsg
+{
public:
IpcIoMsg();
public:
unsigned int requestId; ///< unique for requestor; matches request w/ response
- char buf[IpcIo::BufCapacity]; // XXX: inefficient
off_t offset;
size_t len;
+ Ipc::Mem::PageId page;
IpcIo::Command command; ///< what disker is supposed to do or did
+ struct timeval start; ///< when the I/O request was converted to IpcIoMsg
int xerrno; ///< I/O error code or zero
};
class IpcIoFile: public DiskFile
{
+ CBDATA_CLASS(IpcIoFile);
public:
typedef RefCount<IpcIoFile> Pointer;
virtual ~IpcIoFile();
/* DiskFile API */
+ virtual void configure(const Config &cfg);
virtual void open(int flags, mode_t mode, RefCount<IORequestor> callback);
virtual void create(int flags, mode_t mode, RefCount<IORequestor> callback);
virtual void read(ReadRequest *);
/// handle queue push notifications from worker or disker
static void HandleNotification(const Ipc::TypedMsgHdr &msg);
+ DiskFile::Config config; ///< supported configuration options
+
protected:
friend class IpcIoPendingRequest;
void openCompleted(const Ipc::StrandSearchResponse *const response);
- void readCompleted(ReadRequest *readRequest, const IpcIoMsg *const response);
+ void readCompleted(ReadRequest *readRequest, IpcIoMsg *const response);
void writeCompleted(WriteRequest *writeRequest, const IpcIoMsg *const response);
+ bool canWait() const;
private:
- void trackPendingRequest(IpcIoPendingRequest &pending);
- void push(IpcIoPendingRequest &pending);
+ void trackPendingRequest(const unsigned int id, IpcIoPendingRequest *const pending);
+ void push(IpcIoPendingRequest *const pending);
IpcIoPendingRequest *dequeueRequest(const unsigned int requestId);
static void Notify(const int peerId);
void checkTimeouts();
void scheduleTimeoutCheck();
- void handleResponses();
- void handleResponse(const IpcIoMsg &ipcIo);
+ static void HandleResponses(const char *const when);
+ void handleResponse(IpcIoMsg &ipcIo);
+ static void DiskerHandleMoreRequests(void*);
static void DiskerHandleRequests();
static void DiskerHandleRequest(const int workerId, IpcIoMsg &ipcIo);
+ static bool WaitBeforePop();
private:
- typedef FewToOneBiQueue DiskerQueue;
- typedef OneToOneBiQueue WorkerQueue;
-
const String dbName; ///< the name of the file we are managing
int diskId; ///< the process ID of the disker we talk to
- static DiskerQueue *diskerQueue; ///< IPC queue for disker
- WorkerQueue *workerQueue; ///< IPC queue for worker
RefCount<IORequestor> ioRequestor;
bool error_; ///< whether we have seen at least one I/O error (XXX)
typedef std::map<int, IpcIoFile*> IpcIoFilesMap;
static IpcIoFilesMap IpcIoFiles;
- CBDATA_CLASS2(IpcIoFile);
-};
+ typedef Ipc::FewToFewBiQueue Queue;
+ static std::unique_ptr<Queue> queue; ///< IPC queue
+ /// whether we are waiting for an event to handle still queued I/O requests
+ static bool DiskerHandleMoreRequestsScheduled;
+};
/// keeps original I/O request parameters while disker is handling the request
class IpcIoPendingRequest
IpcIoPendingRequest(const IpcIoFile::Pointer &aFile);
/// called when response is received and, with a nil response, on timeouts
- void completeIo(const IpcIoMsg *const response);
+ void completeIo(IpcIoMsg *const response);
public:
const IpcIoFile::Pointer file; ///< the file object waiting for the response
IpcIoPendingRequest &operator =(const IpcIoPendingRequest &d); // ditto
};
-
#endif /* SQUID_IPC_IOFILE_H */
+