#ifndef SQUID_HELPER_H
#define SQUID_HELPER_H
-#include "squid.h"
+#include "base/AsyncCall.h"
#include "cbdata.h"
-#include "ip/IpAddress.h"
+#include "comm/forward.h"
+#include "dlink.h"
+#include "HelperChildConfig.h"
+#include "HelperReply.h"
+#include "ip/Address.h"
class helper_request;
-typedef struct _helper helper;
+typedef void HLPCB(void *, const HelperReply &reply);
-typedef struct _helper_stateful statefulhelper;
-
-typedef struct _helper_server helper_server;
-
-typedef struct _helper_stateful_server helper_stateful_server;
-
-typedef struct _helper_flags helper_flags;
-
-typedef struct _helper_stateful_flags helper_stateful_flags;
-
-typedef stateful_helper_callback_t HLPSCB(void *, void *lastserver, char *buf);
+class helper
+{
+public:
+ inline helper(const char *name) :
+ cmdline(NULL),
+ id_name(name),
+ ipc_type(0),
+ last_queue_warn(0),
+ last_restart(0),
+ eom('\n') {
+ memset(&stats, 0, sizeof(stats));
+ }
+ ~helper();
-struct _helper {
+public:
wordlist *cmdline;
dlink_list servers;
dlink_list queue;
const char *id_name;
- int n_to_start;
- int n_running;
- int n_active;
+ HelperChildConfig childs; ///< Configuration settings for number running.
int ipc_type;
- IpAddress addr;
- unsigned int concurrency;
+ Ip::Address addr;
time_t last_queue_warn;
time_t last_restart;
+ char eom; ///< The char which marks the end of (response) message, normally '\n'
- struct {
+ struct _stats {
int requests;
int replies;
int queue_size;
int avg_svc_time;
} stats;
+
+private:
+ CBDATA_CLASS2(helper);
};
-struct _helper_stateful {
- wordlist *cmdline;
- dlink_list servers;
- dlink_list queue;
- const char *id_name;
- int n_to_start;
- int n_running;
- int n_active;
- int ipc_type;
- IpAddress addr;
+class statefulhelper : public helper
+{
+public:
+ inline statefulhelper(const char *name) : helper(name), datapool(NULL), IsAvailable(NULL), OnEmptyQueue(NULL) {};
+ inline ~statefulhelper() {};
+
+public:
MemAllocator *datapool;
HLPSAVAIL *IsAvailable;
HLPSONEQ *OnEmptyQueue;
- time_t last_queue_warn;
- time_t last_restart;
- struct {
- int requests;
- int replies;
- int queue_size;
- int avg_svc_time;
- } stats;
+private:
+ CBDATA_CLASS2(statefulhelper);
};
-struct _helper_server {
+/**
+ * Fields shared between stateless and stateful helper servers.
+ */
+class HelperServerBase
+{
+public:
+ /** Closes pipes to the helper safely.
+ * Handles the case where the read and write pipes are the same FD.
+ */
+ void closePipesSafely();
+
+ /** Closes the reading pipe.
+ * If the read and write sockets are the same the write pipe will
+ * also be closed. Otherwise its left open for later handling.
+ */
+ void closeWritePipeSafely();
+
+public:
int index;
int pid;
- IpAddress addr;
- int rfd;
- int wfd;
- MemBuf *wqueue;
- MemBuf *writebuf;
+ Ip::Address addr;
+ Comm::ConnectionPointer readPipe;
+ Comm::ConnectionPointer writePipe;
+ void *hIpc;
+
char *rbuf;
size_t rbuf_sz;
size_t roffset;
struct timeval dispatch_time;
-
struct timeval answer_time;
dlink_node link;
- helper *parent;
- helper_request **requests;
struct _helper_flags {
- unsigned int writing:1;
- unsigned int closing:1;
- unsigned int shutdown:1;
+ bool busy;
+ bool writing;
+ bool closing;
+ bool shutdown;
+ bool reserved;
} flags;
struct {
- int uses;
- unsigned int pending;
+ uint64_t uses; //< requests sent to this helper
+ uint64_t replies; //< replies received from this helper
+ uint64_t pending; //< queued lookups waiting to be sent to this helper
+ uint64_t releases; //< times release() has been called on this helper (if stateful)
} stats;
+ void initStats();
+};
- void *hIpc;
+class MemBuf;
+
+class helper_server : public HelperServerBase
+{
+public:
+ MemBuf *wqueue;
+ MemBuf *writebuf;
+
+ helper *parent;
+ helper_request **requests;
+
+private:
+ CBDATA_CLASS2(helper_server);
};
class helper_stateful_request;
-struct _helper_stateful_server {
- int index;
- int pid;
- IpAddress addr;
- int rfd;
- int wfd;
+class helper_stateful_server : public HelperServerBase
+{
+public:
/* MemBuf wqueue; */
/* MemBuf writebuf; */
- char *rbuf;
- size_t rbuf_sz;
- size_t roffset;
-
- struct timeval dispatch_time;
- struct timeval answer_time;
-
- dlink_node link;
- dlink_list queue;
statefulhelper *parent;
helper_stateful_request *request;
- struct _helper_stateful_flags {
- unsigned int busy:1;
- unsigned int closing:1;
- unsigned int shutdown:1;
- stateful_helper_reserve_t reserved;
- } flags;
-
- struct {
- int uses;
- int submits;
- int releases;
- int deferbyfunc;
- int deferbycb;
- } stats;
- int deferred_requests; /* current number of deferred requests */
void *data; /* State data used by the calling routines */
- void *hIpc;
+
+private:
+ CBDATA_CLASS2(helper_stateful_server);
};
class helper_request
public:
MEMPROXY_CLASS(helper_stateful_request);
char *buf;
- HLPSCB *callback;
- int placeholder; /* if 1, this is a dummy request waiting for a stateful helper to become available for deferred requests.*/
+ HLPCB *callback;
+ int placeholder; /* if 1, this is a dummy request waiting for a stateful helper to become available */
void *data;
};
MEMPROXY_CLASS_INLINE(helper_stateful_request);
/* helper.c */
-SQUIDCEXTERN void helperOpenServers(helper * hlp);
-SQUIDCEXTERN void helperStatefulOpenServers(statefulhelper * hlp);
-SQUIDCEXTERN void helperSubmit(helper * hlp, const char *buf, HLPCB * callback, void *data);
-SQUIDCEXTERN void helperStatefulSubmit(statefulhelper * hlp, const char *buf, HLPSCB * callback, void *data, helper_stateful_server * lastserver);
-SQUIDCEXTERN void helperStats(StoreEntry * sentry, helper * hlp, const char *label = NULL);
-SQUIDCEXTERN void helperStatefulStats(StoreEntry * sentry, statefulhelper * hlp, const char *label = NULL);
-SQUIDCEXTERN void helperShutdown(helper * hlp);
-SQUIDCEXTERN void helperStatefulShutdown(statefulhelper * hlp);
-SQUIDCEXTERN helper *helperCreate(const char *);
-SQUIDCEXTERN statefulhelper *helperStatefulCreate(const char *);
-SQUIDCEXTERN void helperFree(helper *);
-SQUIDCEXTERN void helperStatefulFree(statefulhelper *);
-SQUIDCEXTERN void helperStatefulReset(helper_stateful_server * srv);
-SQUIDCEXTERN void helperStatefulReleaseServer(helper_stateful_server * srv);
-SQUIDCEXTERN void *helperStatefulServerGetData(helper_stateful_server * srv);
-SQUIDCEXTERN helper_stateful_server *helperStatefulDefer(statefulhelper *);
-
-
+void helperOpenServers(helper * hlp);
+void helperStatefulOpenServers(statefulhelper * hlp);
+void helperSubmit(helper * hlp, const char *buf, HLPCB * callback, void *data);
+void helperStatefulSubmit(statefulhelper * hlp, const char *buf, HLPCB * callback, void *data, helper_stateful_server * lastserver);
+void helperStats(StoreEntry * sentry, helper * hlp, const char *label = NULL);
+void helperStatefulStats(StoreEntry * sentry, statefulhelper * hlp, const char *label = NULL);
+void helperShutdown(helper * hlp);
+void helperStatefulShutdown(statefulhelper * hlp);
+void helperStatefulReleaseServer(helper_stateful_server * srv);
+void *helperStatefulServerGetData(helper_stateful_server * srv);
#endif /* SQUID_HELPER_H */