SharedListen.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 1996-2019 The Squid Software Foundation and contributors
3  *
4  * Squid software is distributed under GPLv2+ license and includes
5  * contributions from numerous individuals and organizations.
6  * Please see the COPYING and CONTRIBUTORS files for details.
7  */
8 
9 /* DEBUG: section 54 Interprocess Communication */
10 
11 #include "squid.h"
12 #include "base/TextException.h"
13 #include "comm.h"
14 #include "comm/Connection.h"
15 #include "globals.h"
16 #include "ipc/Kids.h"
17 #include "ipc/Messages.h"
18 #include "ipc/Port.h"
19 #include "ipc/SharedListen.h"
20 #include "ipc/StartListening.h"
21 #include "ipc/TypedMsgHdr.h"
22 #include "tools.h"
23 
24 #include <list>
25 #include <map>
26 
29 {
30 public:
32  AsyncCall::Pointer callback; // who to notify
33 };
34 
36 typedef std::map<int, PendingOpenRequest> SharedListenRequestMap;
38 
40 typedef std::list<PendingOpenRequest> DelayedSharedListenRequests;
42 
43 static int
45 {
46  // find unused ID using linear seach; there should not be many entries
47  for (int id = 0; true; ++id) {
49  TheSharedListenRequestMap[id] = por;
50  return id;
51  }
52  }
53  assert(false); // not reached
54  return -1;
55 }
56 
57 bool
59 {
60  if (sock_type != p.sock_type)
61  return sock_type < p.sock_type;
62 
63  if (proto != p.proto)
64  return proto < p.proto;
65 
66  // ignore flags and fdNote differences because they do not affect binding
67 
68  return addr.compareWhole(p.addr) < 0;
69 }
70 
71 Ipc::SharedListenRequest::SharedListenRequest(): requestorId(-1), mapId(-1)
72 {
73  // caller will then set public data members
74 }
75 
77 {
79  hdrMsg.getPod(*this);
80 }
81 
83 {
85  hdrMsg.putPod(*this);
86 }
87 
88 Ipc::SharedListenResponse::SharedListenResponse(int aFd, int anErrNo, int aMapId):
89  fd(aFd), errNo(anErrNo), mapId(aMapId)
90 {
91 }
92 
94  fd(-1), errNo(0), mapId(-1)
95 {
97  hdrMsg.getPod(*this);
98  fd = hdrMsg.getFd();
99  // other conn details are passed in OpenListenerParams and filled out by SharedListenJoin()
100 }
101 
103 {
105  hdrMsg.putPod(*this);
106  hdrMsg.putFd(fd);
107 }
108 
109 static void
111 {
113  request.requestorId = KidIdentifier;
114  request.params = por.params;
115  request.mapId = AddToMap(por);
116 
117  debugs(54, 3, "getting listening FD for " << request.params.addr <<
118  " mapId=" << request.mapId);
119 
120  Ipc::TypedMsgHdr message;
121  request.pack(message);
123 }
124 
125 static void
127 {
128  if (TheDelayedRequests.empty())
129  return; // no pending requests to resume
130 
131  debugs(54, 3, "resuming with " << TheSharedListenRequestMap.size() <<
132  " active + " << TheDelayedRequests.size() << " delayed requests");
133 
135  TheDelayedRequests.pop_front();
136 }
137 
138 void
140 {
141  PendingOpenRequest por;
142  por.params = params;
143  por.callback = cb;
144 
145  const DelayedSharedListenRequests::size_type concurrencyLimit = 1;
146  if (TheSharedListenRequestMap.size() >= concurrencyLimit) {
147  debugs(54, 3, "waiting for " << TheSharedListenRequestMap.size() <<
148  " active + " << TheDelayedRequests.size() << " delayed requests");
149  TheDelayedRequests.push_back(por);
150  } else {
152  }
153 }
154 
156 {
157  // Dont debugs c fully since only FD is filled right now.
158  debugs(54, 3, "got listening FD " << response.fd << " errNo=" <<
159  response.errNo << " mapId=" << response.mapId << " with " <<
160  TheSharedListenRequestMap.size() << " active + " <<
161  TheDelayedRequests.size() << " delayed requests");
162 
165  Must(por.callback != NULL);
166  TheSharedListenRequestMap.erase(response.mapId);
167 
168  StartListeningCb *cbd = dynamic_cast<StartListeningCb*>(por.callback->getDialer());
169  assert(cbd && cbd->conn != NULL);
170  Must(cbd && cbd->conn != NULL);
171  cbd->conn->fd = response.fd;
172 
173  if (Comm::IsConnOpen(cbd->conn)) {
174  OpenListenerParams &p = por.params;
175  cbd->conn->local = p.addr;
176  cbd->conn->flags = p.flags;
177  // XXX: leave the comm AI stuff to comm_import_opened()?
178  struct addrinfo *AI = NULL;
179  p.addr.getAddrInfo(AI);
180  AI->ai_socktype = p.sock_type;
181  AI->ai_protocol = p.proto;
182  comm_import_opened(cbd->conn, FdNote(p.fdNote), AI);
184  }
185 
186  cbd->errNo = response.errNo;
187  cbd->handlerSubscription = por.params.handlerSubscription;
188  ScheduleCallHere(por.callback);
189 
191 }
192 
const char * FdNote(int fdNodeId)
converts FdNoteId into a string
Definition: FdNotes.cc:16
void getPod(Pod &pod) const
load POD
Definition: TypedMsgHdr.h:50
static void kickDelayedRequest()
#define assert(EX)
Definition: assert.h:17
int mapId
to map future response to the requestor&#39;s callback
Definition: SharedListen.h:71
static void FreeAddr(struct addrinfo *&ai)
Definition: Address.cc:686
void comm_import_opened(const Comm::ConnectionPointer &conn, const char *note, struct addrinfo *AI)
update Comm state after getting a comm_open() FD from another process
Definition: comm.cc:499
SharedListenRequest()
from OpenSharedListen() which then sets public data
Definition: SharedListen.cc:71
struct _request * request(char *urlin)
Definition: tcp-banger2.c:291
std::map< int, PendingOpenRequest > SharedListenRequestMap
maps ID assigned at request time to the response callback
Definition: SharedListen.cc:36
int requestorId
kidId of the requestor
Definition: SharedListen.h:53
void putPod(const Pod &pod)
store POD
Definition: TypedMsgHdr.h:52
Subscription::Pointer handlerSubscription
The subscription we will pass on to the ConnAcceptor.
#define Must(condition)
Like assert() but throws an exception instead of aborting the process.
Definition: TextException.h:69
char * p
Definition: membanger.c:43
Ip::Address addr
will be memset and memcopied
Definition: SharedListen.h:35
void SharedListenJoined(const SharedListenResponse &response)
process Coordinator response to SharedListenRequest
OpenListenerParams params
actual comm_open_sharedListen() parameters
Definition: SharedListen.h:55
static int AddToMap(const PendingOpenRequest &por)
Definition: SharedListen.cc:44
a response to SharedListenRequest
Definition: SharedListen.h:61
bool IsConnOpen(const Comm::ConnectionPointer &conn)
Definition: Connection.cc:24
common API for all StartListening() callbacks
std::list< PendingOpenRequest > DelayedSharedListenRequests
accumulates delayed requests until they are ready to be sent, in FIFO order
Definition: SharedListen.cc:40
static void SendSharedListenRequest(const PendingOpenRequest &por)
#define debugs(SECTION, LEVEL, CONTENT)
Definition: Debug.h:124
static DelayedSharedListenRequests TheDelayedRequests
Definition: SharedListen.cc:41
Comm::ConnectionPointer conn
opened listening socket
Ipc::OpenListenerParams params
actual comm_open_sharedListen() parameters
Definition: SharedListen.cc:31
void * addr
Definition: membanger.c:46
a request for a listen socket with given parameters
Definition: SharedListen.h:45
void getAddrInfo(struct addrinfo *&ai, int force=AF_UNSPEC) const
Definition: Address.cc:599
void SendMessage(const String &toAddress, const TypedMsgHdr &message)
Definition: UdsOp.cc:188
Ip::Address local
Definition: Connection.h:135
int errNo
errno value from the comm_open_listener() call
int fdNote
index into fd_note() comment strings
Definition: SharedListen.h:32
void pack(TypedMsgHdr &hdrMsg) const
prepare for sendmsg()
void JoinSharedListen(const OpenListenerParams &, AsyncCall::Pointer &)
prepare and send SharedListenRequest to Coordinator
bool operator<(const OpenListenerParams &p) const
useful for map<>
Definition: SharedListen.cc:58
int KidIdentifier
void putFd(int aFd)
stores descriptor
Definition: TypedMsgHdr.cc:203
#define ScheduleCallHere(call)
Definition: AsyncCall.h:166
SharedListenResponse(int fd, int errNo, int mapId)
Definition: SharedListen.cc:88
struct msghdr with a known type, fixed-size I/O and control buffers
Definition: TypedMsgHdr.h:31
int errNo
errno value from comm_open_sharedListen() call
Definition: SharedListen.h:70
int getFd() const
returns stored descriptor
Definition: TypedMsgHdr.cc:224
void setType(int aType)
sets message type; use MessageType enum
Definition: TypedMsgHdr.cc:107
int fd
opened listening socket or -1
Definition: SharedListen.h:69
void checkType(int aType) const
throws if stored type is not aType
Definition: TypedMsgHdr.cc:101
void pack(TypedMsgHdr &hdrMsg) const
prepare for sendmsg()
Definition: SharedListen.cc:82
AsyncCall::Pointer callback
Definition: SharedListen.cc:32
"shared listen" is when concurrent processes are listening on the same fd
Definition: SharedListen.h:24
static String CoordinatorAddr()
get the IPC message address for coordinator process
Definition: Port.cc:64
#define NULL
Definition: types.h:166
holds information necessary to handle JoinListen response
Definition: SharedListen.cc:28
static SharedListenRequestMap TheSharedListenRequestMap
Definition: SharedListen.cc:37
int mapId
to map future response to the requestor&#39;s callback
Definition: SharedListen.h:57

 

Introduction

Documentation

Support

Miscellaneous

Web Site Translations

Mirrors