]> git.ipfire.org Git - thirdparty/squid.git/blame - src/ipc/UdsOp.cc
Fix Solaris getrusage wrapping
[thirdparty/squid.git] / src / ipc / UdsOp.cc
CommitLineData
10cefb7b 1/*
2 * $Id$
3 *
4 * DEBUG: section 54 Interprocess Communication
5 *
6 */
7
8
9#include "config.h"
10#include "comm.h"
1bac0258 11#include "CommCalls.h"
ec41b64c 12#include "comm/Write.h"
a67d2b2e 13#include "base/TextException.h"
10cefb7b 14#include "ipc/UdsOp.h"
15
10cefb7b 16
ba568924 17Ipc::UdsOp::UdsOp(const String& pathAddr):
5667a628
AR
18 AsyncJob("Ipc::UdsOp"),
19 address(PathToAddress(pathAddr)),
20 options(COMM_NONBLOCKING),
21 fd_(-1)
10cefb7b 22{
ba568924 23 debugs(54, 5, HERE << '[' << this << "] pathAddr=" << pathAddr);
10cefb7b 24}
25
26Ipc::UdsOp::~UdsOp()
27{
28 debugs(54, 5, HERE << '[' << this << ']');
ba568924 29 if (fd_ >= 0)
10cefb7b 30 comm_close(fd_);
31}
32
ba568924 33void Ipc::UdsOp::setOptions(int newOptions)
10cefb7b 34{
ba568924 35 options = newOptions;
10cefb7b 36}
37
38int Ipc::UdsOp::fd()
39{
40 if (fd_ < 0) {
ba568924 41 if (options & COMM_DOBIND)
1bac0258
AR
42 unlink(address.sun_path);
43 fd_ = comm_open_uds(SOCK_DGRAM, 0, &address, options);
ba568924 44 Must(fd_ >= 0);
10cefb7b 45 }
46 return fd_;
47}
48
ba568924 49void Ipc::UdsOp::setTimeout(int seconds, const char *handlerName)
10cefb7b 50{
4299f876 51 typedef CommCbMemFunT<UdsOp, CommTimeoutCbParams> Dialer;
ba568924 52 AsyncCall::Pointer handler = asyncCall(54,5, handlerName,
4299f876 53 Dialer(CbcPointer<UdsOp>(this), &UdsOp::noteTimeout));
ba568924
AR
54 commSetTimeout(fd(), seconds, handler);
55}
56
57void Ipc::UdsOp::clearTimeout()
58{
59 commSetTimeout(fd(), -1, NULL, NULL); // TODO: add Comm::ClearTimeout(fd)
60}
61
62void Ipc::UdsOp::noteTimeout(const CommTimeoutCbParams &)
63{
64 timedout(); // our kid handles communication timeout
10cefb7b 65}
66
67
1bac0258 68struct sockaddr_un
5667a628 69Ipc::PathToAddress(const String& pathAddr) {
1bac0258
AR
70 assert(pathAddr.size() != 0);
71 struct sockaddr_un unixAddr;
72 memset(&unixAddr, 0, sizeof(unixAddr));
73 unixAddr.sun_family = AF_LOCAL;
74 xstrncpy(unixAddr.sun_path, pathAddr.termedBuf(), sizeof(unixAddr.sun_path));
75 return unixAddr;
76}
77
78
10cefb7b 79CBDATA_NAMESPACED_CLASS_INIT(Ipc, UdsSender);
80
1bac0258 81Ipc::UdsSender::UdsSender(const String& pathAddr, const TypedMsgHdr& aMessage):
5667a628
AR
82 UdsOp(pathAddr),
83 message(aMessage),
84 retries(10), // TODO: make configurable?
85 timeout(10), // TODO: make configurable?
86 writing(false)
10cefb7b 87{
1bac0258 88 message.address(address);
10cefb7b 89}
90
91void Ipc::UdsSender::start()
92{
ba568924 93 UdsOp::start();
10cefb7b 94 write();
95 if (timeout > 0)
ba568924 96 setTimeout(timeout, "Ipc::UdsSender::noteTimeout");
10cefb7b 97}
98
ba568924 99bool Ipc::UdsSender::doneAll() const
10cefb7b 100{
ba568924 101 return !writing && UdsOp::doneAll();
10cefb7b 102}
103
104void Ipc::UdsSender::write()
105{
106 debugs(54, 5, HERE);
4299f876
AR
107 typedef CommCbMemFunT<UdsSender, CommIoCbParams> Dialer;
108 AsyncCall::Pointer writeHandler = JobCallback(54, 5,
4cb2536f 109 Dialer, this, UdsSender::wrote);
ec41b64c 110 Comm::Write(fd(), message.raw(), message.size(), writeHandler, NULL);
ba568924 111 writing = true;
10cefb7b 112}
113
ba568924 114void Ipc::UdsSender::wrote(const CommIoCbParams& params)
10cefb7b 115{
116 debugs(54, 5, HERE << "FD " << params.fd << " flag " << params.flag << " [" << this << ']');
ba568924 117 writing = false;
1bac0258
AR
118 if (params.flag != COMM_OK && retries-- > 0) {
119 sleep(1); // do not spend all tries at once; XXX: use an async timed event instead of blocking here; store the time when we started writing so that we do not sleep if not needed?
ba568924 120 write(); // XXX: should we close on error so that fd() reopens?
1bac0258 121 }
10cefb7b 122}
123
ba568924 124void Ipc::UdsSender::timedout()
10cefb7b 125{
126 debugs(54, 5, HERE);
ba568924 127 mustStop("timedout");
10cefb7b 128}
129
130
1bac0258 131void Ipc::SendMessage(const String& toAddress, const TypedMsgHdr &message)
10cefb7b 132{
4299f876 133 AsyncJob::Start(new UdsSender(toAddress, message));
10cefb7b 134}