]>
git.ipfire.org Git - thirdparty/squid.git/blob - src/ipc/UdsOp.cc
4 * DEBUG: section 54 Interprocess Communication
11 #include "CommCalls.h"
12 #include "comm/Write.h"
13 #include "base/TextException.h"
14 #include "ipc/UdsOp.h"
17 Ipc :: UdsOp :: UdsOp ( const String
& pathAddr
):
18 AsyncJob ( "Ipc::UdsOp" ),
19 address ( PathToAddress ( pathAddr
)),
20 options ( COMM_NONBLOCKING
),
23 debugs ( 54 , 5 , HERE
<< '[' << this << "] pathAddr=" << pathAddr
);
28 debugs ( 54 , 5 , HERE
<< '[' << this << ']' );
33 void Ipc :: UdsOp :: setOptions ( int newOptions
)
41 if ( options
& COMM_DOBIND
)
42 unlink ( address
. sun_path
);
43 fd_
= comm_open_uds ( SOCK_DGRAM
, 0 , & address
, options
);
49 void Ipc :: UdsOp :: setTimeout ( int seconds
, const char * handlerName
)
51 typedef CommCbMemFunT
< UdsOp
, CommTimeoutCbParams
> Dialer
;
52 AsyncCall :: Pointer handler
= asyncCall ( 54 , 5 , handlerName
,
53 Dialer ( CbcPointer
< UdsOp
>( this ), & UdsOp :: noteTimeout
));
54 commSetTimeout ( fd (), seconds
, handler
);
57 void Ipc :: UdsOp :: clearTimeout ()
59 commSetTimeout ( fd (), - 1 , NULL
, NULL
); // TODO: add Comm::ClearTimeout(fd)
62 void Ipc :: UdsOp :: noteTimeout ( const CommTimeoutCbParams
&)
64 timedout (); // our kid handles communication timeout
69 Ipc :: PathToAddress ( const String
& pathAddr
) {
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
));
79 CBDATA_NAMESPACED_CLASS_INIT ( Ipc
, UdsSender
);
81 Ipc :: UdsSender :: UdsSender ( const String
& pathAddr
, const TypedMsgHdr
& aMessage
):
84 retries ( 10 ), // TODO: make configurable?
85 timeout ( 10 ), // TODO: make configurable?
88 message
. address ( address
);
91 void Ipc :: UdsSender :: start ()
96 setTimeout ( timeout
, "Ipc::UdsSender::noteTimeout" );
99 bool Ipc :: UdsSender :: doneAll () const
101 return ! writing
&& UdsOp :: doneAll ();
104 void Ipc :: UdsSender :: write ()
107 typedef CommCbMemFunT
< UdsSender
, CommIoCbParams
> Dialer
;
108 AsyncCall :: Pointer writeHandler
= JobCallback ( 54 , 5 ,
109 Dialer
, this , UdsSender :: wrote
);
110 Comm :: Write ( fd (), message
. raw (), message
. size (), writeHandler
, NULL
);
114 void Ipc :: UdsSender :: wrote ( const CommIoCbParams
& params
)
116 debugs ( 54 , 5 , HERE
<< "FD " << params
. fd
<< " flag " << params
. flag
<< " retries " << retries
<< " [" << this << ']' );
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?
120 write (); // XXX: should we close on error so that fd() reopens?
124 void Ipc :: UdsSender :: timedout ()
127 mustStop ( "timedout" );
131 void Ipc :: SendMessage ( const String
& toAddress
, const TypedMsgHdr
& message
)
133 AsyncJob :: Start ( new UdsSender ( toAddress
, message
));
136 int Ipc :: ImportFdIntoComm ( int fd
, int socktype
, int protocol
, Ipc :: FdNoteId noteId
)
138 struct sockaddr_in addr
;
139 socklen_t len
= sizeof ( addr
);
140 if ( getsockname ( fd
, reinterpret_cast < sockaddr
*>(& addr
), & len
) == 0 ) {
141 Ip :: Address
ipAddr ( addr
);
142 struct addrinfo
* addr_info
= NULL
;
143 ipAddr
. GetAddrInfo ( addr_info
);
144 addr_info
-> ai_socktype
= socktype
;
145 addr_info
-> ai_protocol
= protocol
;
146 comm_import_opened ( fd
, ipAddr
, COMM_NONBLOCKING
, Ipc :: FdNote ( noteId
), addr_info
);
147 ipAddr
. FreeAddrInfo ( addr_info
);
149 debugs ( 54 , DBG_CRITICAL
, HERE
<< "ERROR: FD " << fd
<< ' ' << xstrerror ());