#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_flags helper_flags;
-
-typedef struct _helper_stateful_flags helper_stateful_flags;
-
-typedef void HLPSCB(void *, void *lastserver, char *buf);
+typedef void HLPCB(void *, const HelperReply &reply);
class helper
{
public:
- inline helper(const char *name) : cmdline(NULL), id_name(name) {};
+ 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();
public:
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 _stats {
int requests;
class statefulhelper : public helper
{
public:
- inline statefulhelper(const char *name) : helper(name) {};
+ inline statefulhelper(const char *name) : helper(name), datapool(NULL), IsAvailable(NULL), OnEmptyQueue(NULL) {};
inline ~statefulhelper() {};
public:
CBDATA_CLASS2(statefulhelper);
};
-/*
+/**
* 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;
Ip::Address addr;
- int rfd;
- int wfd;
+ Comm::ConnectionPointer readPipe;
+ Comm::ConnectionPointer writePipe;
void *hIpc;
char *rbuf;
struct timeval answer_time;
dlink_node link;
+
+ struct _helper_flags {
+ bool busy;
+ bool writing;
+ bool closing;
+ bool shutdown;
+ bool reserved;
+ } flags;
+
+ struct {
+ 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();
};
+class MemBuf;
+
class helper_server : public HelperServerBase
{
public:
helper *parent;
helper_request **requests;
- struct _helper_flags {
- unsigned int writing:1;
- unsigned int closing:1;
- unsigned int shutdown:1;
- } flags;
-
- struct {
- int uses;
- unsigned int pending;
- } stats;
+private:
+ CBDATA_CLASS2(helper_server);
};
class helper_stateful_request;
statefulhelper *parent;
helper_stateful_request *request;
- struct _helper_stateful_flags {
- unsigned int busy:1;
- unsigned int closing:1;
- unsigned int shutdown:1;
- unsigned int reserved:1;
- } flags;
-
- struct {
- int uses;
- int submits;
- int releases;
- } stats;
void *data; /* State data used by the calling routines */
+
+private:
+ CBDATA_CLASS2(helper_stateful_server);
};
class helper_request
public:
MEMPROXY_CLASS(helper_stateful_request);
char *buf;
- HLPSCB *callback;
+ 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 void helperStatefulReleaseServer(helper_stateful_server * srv);
-SQUIDCEXTERN void *helperStatefulServerGetData(helper_stateful_server * srv);
-
+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 */