1 /* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
2 /* vim: set ts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
8 #include "UnixSocketWatcher.h"
13 UnixSocketWatcher::~UnixSocketWatcher()
17 void UnixSocketWatcher::Close()
19 MOZ_ASSERT(MessageLoopForIO::current() == GetIOLoop());
21 mConnectionStatus
= SOCKET_IS_DISCONNECTED
;
22 UnixFdWatcher::Close();
26 UnixSocketWatcher::Connect(const struct sockaddr
* aAddr
, socklen_t aAddrLen
)
28 MOZ_ASSERT(MessageLoopForIO::current() == GetIOLoop());
30 MOZ_ASSERT(aAddr
|| !aAddrLen
);
32 if (connect(GetFd(), aAddr
, aAddrLen
) < 0) {
33 if (errno
== EINPROGRESS
) {
34 mConnectionStatus
= SOCKET_IS_CONNECTING
;
35 // Set up a write watch to receive the connect signal
36 AddWatchers(WRITE_WATCHER
, false);
38 OnError("connect", errno
);
40 return NS_ERROR_FAILURE
;
43 mConnectionStatus
= SOCKET_IS_CONNECTED
;
50 UnixSocketWatcher::Listen(const struct sockaddr
* aAddr
, socklen_t aAddrLen
)
52 MOZ_ASSERT(MessageLoopForIO::current() == GetIOLoop());
54 MOZ_ASSERT(aAddr
|| !aAddrLen
);
56 if (bind(GetFd(), aAddr
, aAddrLen
) < 0) {
57 OnError("bind", errno
);
58 return NS_ERROR_FAILURE
;
60 if (listen(GetFd(), 1) < 0) {
61 OnError("listen", errno
);
62 return NS_ERROR_FAILURE
;
64 mConnectionStatus
= SOCKET_IS_LISTENING
;
70 UnixSocketWatcher::UnixSocketWatcher(MessageLoop
* aIOLoop
)
71 : UnixFdWatcher(aIOLoop
)
72 , mConnectionStatus(SOCKET_IS_DISCONNECTED
)
76 UnixSocketWatcher::UnixSocketWatcher(MessageLoop
* aIOLoop
, int aFd
,
77 ConnectionStatus aConnectionStatus
)
78 : UnixFdWatcher(aIOLoop
, aFd
)
79 , mConnectionStatus(aConnectionStatus
)
84 UnixSocketWatcher::SetSocket(int aFd
, ConnectionStatus aConnectionStatus
)
86 MOZ_ASSERT(MessageLoopForIO::current() == GetIOLoop());
89 mConnectionStatus
= aConnectionStatus
;
93 UnixSocketWatcher::OnFileCanReadWithoutBlocking(int aFd
)
95 MOZ_ASSERT(MessageLoopForIO::current() == GetIOLoop());
96 MOZ_ASSERT(aFd
== GetFd());
98 if (mConnectionStatus
== SOCKET_IS_CONNECTED
) {
99 OnSocketCanReceiveWithoutBlocking();
100 } else if (mConnectionStatus
== SOCKET_IS_LISTENING
) {
102 socklen_t addrLen
= sizeof(addr
);
103 int fd
= TEMP_FAILURE_RETRY(accept(GetFd(),
104 reinterpret_cast<struct sockaddr
*>(&addr
), &addrLen
));
106 OnError("accept", errno
);
108 OnAccepted(fd
, &addr
, addrLen
);
111 NS_NOTREACHED("invalid connection state for reading");
116 UnixSocketWatcher::OnFileCanWriteWithoutBlocking(int aFd
)
118 MOZ_ASSERT(MessageLoopForIO::current() == GetIOLoop());
119 MOZ_ASSERT(aFd
== GetFd());
121 if (mConnectionStatus
== SOCKET_IS_CONNECTED
) {
122 OnSocketCanSendWithoutBlocking();
123 } else if (mConnectionStatus
== SOCKET_IS_CONNECTING
) {
124 RemoveWatchers(WRITE_WATCHER
);
126 socklen_t len
= sizeof(error
);
127 if (getsockopt(GetFd(), SOL_SOCKET
, SO_ERROR
, &error
, &len
) < 0) {
128 OnError("getsockopt", errno
);
130 OnError("connect", error
);
132 mConnectionStatus
= SOCKET_IS_CONNECTED
;
136 NS_NOTREACHED("invalid connection state for writing");