Fix WakeEvent::Open() (#8551)
* Fix WakeEvent::Open()
#### Problem
Some tests were reporting,
```
CHIP:CSL: System wake event notify failed: OS Error 0x02000009: Bad file descriptor
```
but not failing.
#### Change overview
- Fix the problem (setting `mWriteFD` too late in `WakeEvent::Open()`).
- Add error returns and checks so that affected tests actually fail
without the above fix.
#### Testing
With the added error handling, but without the WakeEvent::Open() change,
numerous tests fail.
* review
* review
* fix missed #else case
diff --git a/src/inet/EndPointBasis.cpp b/src/inet/EndPointBasis.cpp
index 339051b..374057b 100644
--- a/src/inet/EndPointBasis.cpp
+++ b/src/inet/EndPointBasis.cpp
@@ -39,7 +39,7 @@
#endif // CHIP_SYSTEM_CONFIG_USE_LWIP
#if CHIP_SYSTEM_CONFIG_USE_SOCKETS
- mSocket.Init(aInetLayer.SystemLayer()->WatchableEvents());
+ (void) mSocket.Init(aInetLayer.SystemLayer()->WatchableEvents());
#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS
}
diff --git a/src/inet/IPEndPointBasis.cpp b/src/inet/IPEndPointBasis.cpp
index 5eb7d82..63c8c08 100644
--- a/src/inet/IPEndPointBasis.cpp
+++ b/src/inet/IPEndPointBasis.cpp
@@ -941,7 +941,7 @@
const int fd = ::socket(family, aType, aProtocol);
if (fd == -1)
return chip::System::MapErrorPOSIX(errno);
- mSocket.Attach(fd);
+ ReturnErrorOnFailure(mSocket.Attach(fd));
mAddrType = aAddressType;
diff --git a/src/inet/RawEndPoint.cpp b/src/inet/RawEndPoint.cpp
index c1df86b..c5580ee 100644
--- a/src/inet/RawEndPoint.cpp
+++ b/src/inet/RawEndPoint.cpp
@@ -425,7 +425,7 @@
#if CHIP_SYSTEM_CONFIG_USE_SOCKETS
// Wait for ability to read on this endpoint.
mSocket.SetCallback(HandlePendingIO, reinterpret_cast<intptr_t>(this));
- mSocket.RequestCallbackOnPendingRead();
+ ReturnErrorOnFailure(mSocket.RequestCallbackOnPendingRead());
#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS
return CHIP_NO_ERROR;
diff --git a/src/inet/TCPEndPoint.cpp b/src/inet/TCPEndPoint.cpp
index 1d58cab..661ab52 100644
--- a/src/inet/TCPEndPoint.cpp
+++ b/src/inet/TCPEndPoint.cpp
@@ -300,17 +300,19 @@
#if CHIP_SYSTEM_CONFIG_USE_SOCKETS
if (listen(mSocket.GetFD(), backlog) != 0)
+ {
res = chip::System::MapErrorPOSIX(errno);
+ }
else
{
// Enable non-blocking mode for the socket.
int flags = fcntl(mSocket.GetFD(), F_GETFL, 0);
fcntl(mSocket.GetFD(), F_SETFL, flags | O_NONBLOCK);
- }
- // Wait for ability to read on this endpoint.
- mSocket.SetCallback(HandlePendingIO, reinterpret_cast<intptr_t>(this));
- mSocket.RequestCallbackOnPendingRead();
+ // Wait for ability to read on this endpoint.
+ mSocket.SetCallback(HandlePendingIO, reinterpret_cast<intptr_t>(this));
+ res = mSocket.RequestCallbackOnPendingRead();
+ }
#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS
@@ -527,7 +529,7 @@
{
State = kState_Connected;
// Wait for ability to read on this endpoint.
- mSocket.RequestCallbackOnPendingRead();
+ ReturnErrorOnFailure(mSocket.RequestCallbackOnPendingRead());
if (OnConnectComplete != nullptr)
OnConnectComplete(this, CHIP_NO_ERROR);
}
@@ -535,7 +537,7 @@
{
State = kState_Connecting;
// Wait for ability to write on this endpoint.
- mSocket.RequestCallbackOnPendingWrite();
+ ReturnErrorOnFailure(mSocket.RequestCallbackOnPendingWrite());
}
#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS
@@ -800,7 +802,7 @@
mSendQueue = std::move(data);
#if CHIP_SYSTEM_CONFIG_USE_SOCKETS
// Wait for ability to write on this endpoint.
- mSocket.RequestCallbackOnPendingWrite();
+ ReturnErrorOnFailure(mSocket.RequestCallbackOnPendingWrite());
#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS
}
else
@@ -1423,7 +1425,11 @@
if (mSendQueue.IsNull())
{
// Do not wait for ability to write on this endpoint.
- mSocket.ClearCallbackOnPendingWrite();
+ err = mSocket.ClearCallbackOnPendingWrite();
+ if (err != CHIP_NO_ERROR)
+ {
+ break;
+ }
}
}
@@ -1526,8 +1532,16 @@
#if CHIP_SYSTEM_CONFIG_USE_SOCKETS
// Wait for ability to read or write on this endpoint.
- mSocket.RequestCallbackOnPendingRead();
- mSocket.RequestCallbackOnPendingWrite();
+ err = mSocket.RequestCallbackOnPendingRead();
+ if (err == CHIP_NO_ERROR)
+ {
+ err = mSocket.RequestCallbackOnPendingWrite();
+ }
+ if (err != CHIP_NO_ERROR)
+ {
+ DoClose(err, false);
+ return;
+ }
#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS
if (OnConnectComplete != nullptr)
@@ -1536,7 +1550,9 @@
// Otherwise, close the connection with an error.
else
+ {
DoClose(err, false);
+ }
}
CHIP_ERROR TCPEndPoint::DoClose(CHIP_ERROR err, bool suppressCallback)
@@ -1654,8 +1670,7 @@
ChipLogError(Inet, "SO_LINGER: %d", errno);
}
- if (mSocket.Close() != 0 && err == CHIP_NO_ERROR)
- err = chip::System::MapErrorPOSIX(errno);
+ mSocket.Close();
}
}
@@ -2420,7 +2435,7 @@
const int fd = ::socket(family, SOCK_STREAM | SOCK_FLAGS, 0);
if (fd == -1)
return chip::System::MapErrorPOSIX(errno);
- mSocket.Attach(fd);
+ ReturnErrorOnFailure(mSocket.Attach(fd));
mAddrType = addrType;
// If creating an IPv6 socket, tell the kernel that it will be IPv6 only. This makes it
@@ -2447,7 +2462,9 @@
#endif // defined(SO_NOSIGPIPE)
}
else if (mAddrType != addrType)
+ {
return CHIP_ERROR_INCORRECT_STATE;
+ }
return CHIP_NO_ERROR;
}
@@ -2616,7 +2633,7 @@
else
State = kState_Closing;
// Do not wait for ability to read on this endpoint.
- mSocket.ClearCallbackOnPendingRead();
+ (void) mSocket.ClearCallbackOnPendingRead();
// Call the app's OnPeerClose.
if (OnPeerClose != nullptr)
OnPeerClose(this);
@@ -2713,37 +2730,40 @@
if (err == CHIP_NO_ERROR)
{
// Put the new end point into the Connected state.
- conEP->mSocket.Attach(conSocket);
- conEP->State = kState_Connected;
+ err = conEP->mSocket.Attach(conSocket);
+ if (err == CHIP_NO_ERROR)
+ {
+ conEP->State = kState_Connected;
#if INET_CONFIG_ENABLE_IPV4
- conEP->mAddrType = (sa.any.sa_family == AF_INET6) ? kIPAddressType_IPv6 : kIPAddressType_IPv4;
+ conEP->mAddrType = (sa.any.sa_family == AF_INET6) ? kIPAddressType_IPv6 : kIPAddressType_IPv4;
#else // !INET_CONFIG_ENABLE_IPV4
- conEP->mAddrType = kIPAddressType_IPv6;
+ conEP->mAddrType = kIPAddressType_IPv6;
#endif // !INET_CONFIG_ENABLE_IPV4
- conEP->Retain();
+ conEP->Retain();
- // Wait for ability to read on this endpoint.
- conEP->mSocket.SetCallback(HandlePendingIO, reinterpret_cast<intptr_t>(conEP));
- conEP->mSocket.RequestCallbackOnPendingRead();
-
- // Call the app's callback function.
- OnConnectionReceived(this, conEP, peerAddr, peerPort);
+ // Wait for ability to read on this endpoint.
+ conEP->mSocket.SetCallback(HandlePendingIO, reinterpret_cast<intptr_t>(conEP));
+ err = conEP->mSocket.RequestCallbackOnPendingRead();
+ if (err == CHIP_NO_ERROR)
+ {
+ // Call the app's callback function.
+ OnConnectionReceived(this, conEP, peerAddr, peerPort);
+ return;
+ }
+ }
}
// Otherwise immediately close the connection, clean up and call the app's error callback.
- else
+ if (conSocket != -1)
+ close(conSocket);
+ if (conEP != nullptr)
{
- if (conSocket != -1)
- close(conSocket);
- if (conEP != nullptr)
- {
- if (conEP->State == kState_Connected)
- conEP->Release();
+ if (conEP->State == kState_Connected)
conEP->Release();
- }
- if (OnAcceptError != nullptr)
- OnAcceptError(this, err);
+ conEP->Release();
}
+ if (OnAcceptError != nullptr)
+ OnAcceptError(this, err);
}
#if INET_CONFIG_OVERRIDE_SYSTEM_TCP_USER_TIMEOUT
diff --git a/src/inet/UDPEndPoint.cpp b/src/inet/UDPEndPoint.cpp
index df06a51..aebc428 100644
--- a/src/inet/UDPEndPoint.cpp
+++ b/src/inet/UDPEndPoint.cpp
@@ -351,7 +351,7 @@
#if CHIP_SYSTEM_CONFIG_USE_SOCKETS
// Wait for ability to read on this endpoint.
mSocket.SetCallback(HandlePendingIO, reinterpret_cast<intptr_t>(this));
- mSocket.RequestCallbackOnPendingRead();
+ ReturnErrorOnFailure(mSocket.RequestCallbackOnPendingRead());
#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS
return CHIP_NO_ERROR;
diff --git a/src/lib/support/CodeUtils.h b/src/lib/support/CodeUtils.h
index 0da7e47..d9afb28 100644
--- a/src/lib/support/CodeUtils.h
+++ b/src/lib/support/CodeUtils.h
@@ -532,6 +532,30 @@
#define VerifyOrDieWithMsg(aCondition, aModule, aMessage, ...) \
nlABORT_ACTION(aCondition, ChipLogDetail(aModule, aMessage, ##__VA_ARGS__))
+/**
+ * @def LogErrorOnFailure(expr)
+ *
+ * @brief
+ * Logs a message if the expression returns something different than CHIP_NO_ERROR.
+ *
+ * Example usage:
+ *
+ * @code
+ * ReturnLogErrorOnFailure(channel->SendMsg(msg));
+ * @endcode
+ *
+ * @param[in] expr A scalar expression to be evaluated against CHIP_NO_ERROR.
+ */
+#define LogErrorOnFailure(expr) \
+ do \
+ { \
+ CHIP_ERROR __err = (expr); \
+ if (__err != CHIP_NO_ERROR) \
+ { \
+ ChipLogError(NotSpecified, "%s at %s:%d", ErrorStr(__err), __FILE__, __LINE__); \
+ } \
+ } while (false)
+
#if (__cplusplus >= 201103L)
#ifndef __FINAL
diff --git a/src/platform/Linux/MdnsImpl.cpp b/src/platform/Linux/MdnsImpl.cpp
index 9a2f92f..042a7f5 100644
--- a/src/platform/Linux/MdnsImpl.cpp
+++ b/src/platform/Linux/MdnsImpl.cpp
@@ -163,11 +163,17 @@
VerifyOrDie(callback != nullptr && fd >= 0);
auto watch = std::make_unique<AvahiWatch>();
- watch->mSocket.Init(*mWatchableEvents)
- .Attach(fd)
- .SetCallback(AvahiWatchCallbackTrampoline, reinterpret_cast<intptr_t>(watch.get()))
- .RequestCallbackOnPendingRead(event & AVAHI_WATCH_IN)
- .RequestCallbackOnPendingWrite(event & AVAHI_WATCH_OUT);
+ watch->mSocket.Init(*mWatchableEvents);
+ LogErrorOnFailure(watch->mSocket.Attach(fd));
+ watch->mSocket.SetCallback(AvahiWatchCallbackTrampoline, reinterpret_cast<intptr_t>(watch.get()));
+ if (event & AVAHI_WATCH_IN)
+ {
+ LogErrorOnFailure(watch->mSocket.RequestCallbackOnPendingRead());
+ }
+ if (event & AVAHI_WATCH_OUT)
+ {
+ LogErrorOnFailure(watch->mSocket.RequestCallbackOnPendingWrite());
+ }
watch->mCallback = callback;
watch->mContext = context;
watch->mPoller = this;
@@ -180,19 +186,19 @@
{
if (event & AVAHI_WATCH_IN)
{
- watch->mSocket.RequestCallbackOnPendingRead();
+ LogErrorOnFailure(watch->mSocket.RequestCallbackOnPendingRead());
}
else
{
- watch->mSocket.ClearCallbackOnPendingRead();
+ LogErrorOnFailure(watch->mSocket.ClearCallbackOnPendingRead());
}
if (event & AVAHI_WATCH_OUT)
{
- watch->mSocket.RequestCallbackOnPendingWrite();
+ LogErrorOnFailure(watch->mSocket.RequestCallbackOnPendingWrite());
}
else
{
- watch->mSocket.ClearCallbackOnPendingWrite();
+ LogErrorOnFailure(watch->mSocket.ClearCallbackOnPendingWrite());
}
}
diff --git a/src/system/SystemLayer.cpp b/src/system/SystemLayer.cpp
index 6bf40d9..8c7ac6e 100644
--- a/src/system/SystemLayer.cpp
+++ b/src/system/SystemLayer.cpp
@@ -92,7 +92,7 @@
return CHIP_ERROR_INCORRECT_STATE;
#if CHIP_SYSTEM_CONFIG_USE_SOCKETS
- mWatchableEvents.Init(*this);
+ ReturnErrorOnFailure(mWatchableEvents.Init(*this));
#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS
#if CHIP_SYSTEM_CONFIG_USE_LWIP
this->AddEventHandlerDelegate(sSystemEventHandlerDelegate);
@@ -119,7 +119,7 @@
}
#if CHIP_SYSTEM_CONFIG_USE_SOCKETS
- mWatchableEvents.Shutdown();
+ ReturnErrorOnFailure(mWatchableEvents.Shutdown());
#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS
this->mLayerState = kLayerState_NotInitialized;
diff --git a/src/system/WakeEvent.cpp b/src/system/WakeEvent.cpp
index e0e387a..d9b9ca9 100644
--- a/src/system/WakeEvent.cpp
+++ b/src/system/WakeEvent.cpp
@@ -71,30 +71,21 @@
if (SetNonBlockingMode(fds[FD_WRITE]) < 0)
return chip::System::MapErrorPOSIX(errno);
- mFD.Init(watchState);
- mFD.Attach(fds[FD_READ]);
- mFD.SetCallback(Confirm, reinterpret_cast<intptr_t>(this));
- mFD.RequestCallbackOnPendingRead();
-
mWriteFD = fds[FD_WRITE];
+ mFD.Init(watchState);
+ ReturnErrorOnFailure(mFD.Attach(fds[FD_READ]));
+ mFD.SetCallback(Confirm, reinterpret_cast<intptr_t>(this));
+ ReturnErrorOnFailure(mFD.RequestCallbackOnPendingRead());
+
return CHIP_NO_ERROR;
}
-CHIP_ERROR WakeEvent::Close()
+void WakeEvent::Close()
{
- int res = 0;
-
- res |= mFD.Close();
- res |= ::close(mWriteFD);
+ mFD.Close();
+ VerifyOrDie(::close(mWriteFD) == 0);
mWriteFD = -1;
-
- if (res < 0)
- {
- return chip::System::MapErrorPOSIX(errno);
- }
-
- return CHIP_NO_ERROR;
}
void WakeEvent::Confirm()
@@ -144,16 +135,9 @@
return CHIP_NO_ERROR;
}
-CHIP_ERROR WakeEvent::Close()
+void WakeEvent::Close()
{
- int res = mFD.Close();
-
- if (res < 0)
- {
- return chip::System::MapErrorPOSIX(errno);
- }
-
- return CHIP_NO_ERROR;
+ mFD.Close();
}
void WakeEvent::Confirm()
diff --git a/src/system/WakeEvent.h b/src/system/WakeEvent.h
index 54465ed..727a64d 100644
--- a/src/system/WakeEvent.h
+++ b/src/system/WakeEvent.h
@@ -46,7 +46,7 @@
{
public:
CHIP_ERROR Open(WatchableEventManager & watchState); /**< Initialize the pipeline */
- CHIP_ERROR Close(); /**< Close both ends of the pipeline. */
+ void Close(); /**< Close both ends of the pipeline. */
CHIP_ERROR Notify(); /**< Set the event. */
void Confirm(); /**< Clear the event. */
diff --git a/src/system/WatchableEventManager.h b/src/system/WatchableEventManager.h
index bf22645..0ab91ce 100644
--- a/src/system/WatchableEventManager.h
+++ b/src/system/WatchableEventManager.h
@@ -41,9 +41,9 @@
*
* It MUST provide at least three methods:
*
- * - void Init(System::Layer & systemLayer) -- called from System::Layer::Init()
- * - void Shutdown() -- called from System::Layer::Shutdown()
- * - void Signal() -- called to indicate that event monitoring may need to be refreshed or resumed.
+ * - CHIP_ERROR Init(System::Layer & systemLayer) -- called from System::Layer::Init()
+ * - CHIP_ERROR Shutdown() -- called from System::Layer::Shutdown()
+ * - void Signal() -- called to indicate that event monitoring may need to be refreshed or resumed.
*
* Other contents depend on the contract between socket-event implementation and platform layer implementation.
* For POSIX-like platforms, WatchableEventManager provides a set of functions called from the event loop:
diff --git a/src/system/WatchableEventManagerLibevent.cpp b/src/system/WatchableEventManagerLibevent.cpp
index 8517b29..141b95f 100644
--- a/src/system/WatchableEventManagerLibevent.cpp
+++ b/src/system/WatchableEventManagerLibevent.cpp
@@ -61,7 +61,7 @@
} // anonymous namespace
-void WatchableEventManager::Init(System::Layer & systemLayer)
+CHIP_ERROR WatchableEventManager::Init(System::Layer & systemLayer)
{
#if CHIP_CONFIG_LIBEVENT_DEBUG_CHECKS
static bool enabled_event_debug_mode = false;
@@ -76,6 +76,7 @@
mTimeoutEvent = evtimer_new(mEventBase, TimeoutCallbackHandler, event_self_cbarg());
mActiveSockets = nullptr;
mSystemLayer = &systemLayer;
+ return CHIP_NO_ERROR;
}
void WatchableEventManager::PrepareEvents()
@@ -117,13 +118,14 @@
}
}
-void WatchableEventManager::Shutdown()
+CHIP_ERROR WatchableEventManager::Shutdown()
{
event_base_loopbreak(mEventBase);
event_free(mTimeoutEvent);
mTimeoutEvent = nullptr;
event_base_free(mEventBase);
mEventBase = nullptr;
+ return CHIP_NO_ERROR;
}
void WatchableEventManager::Signal()
diff --git a/src/system/WatchableEventManagerLibevent.h b/src/system/WatchableEventManagerLibevent.h
index 828b356..5bbab07 100644
--- a/src/system/WatchableEventManagerLibevent.h
+++ b/src/system/WatchableEventManagerLibevent.h
@@ -37,8 +37,8 @@
{
public:
WatchableEventManager() : mActiveSockets(nullptr), mSystemLayer(nullptr), mEventBase(nullptr), mTimeoutEvent(nullptr) {}
- void Init(Layer & systemLayer);
- void Shutdown();
+ CHIP_ERROR Init(Layer & systemLayer);
+ CHIP_ERROR Shutdown();
void Signal();
void EventLoopBegins() {}
diff --git a/src/system/WatchableEventManagerSelect.cpp b/src/system/WatchableEventManagerSelect.cpp
index f1f975b..a46fd95 100644
--- a/src/system/WatchableEventManagerSelect.cpp
+++ b/src/system/WatchableEventManagerSelect.cpp
@@ -45,7 +45,7 @@
namespace chip {
namespace System {
-void WatchableEventManager::Init(Layer & systemLayer)
+CHIP_ERROR WatchableEventManager::Init(Layer & systemLayer)
{
mSystemLayer = &systemLayer;
mMaxFd = -1;
@@ -54,13 +54,14 @@
FD_ZERO(&mRequest.mErrorSet);
// Create an event to allow an arbitrary thread to wake the thread in the select loop.
- mWakeEvent.Open(*this);
+ return mWakeEvent.Open(*this);
}
-void WatchableEventManager::Shutdown()
+CHIP_ERROR WatchableEventManager::Shutdown()
{
mWakeEvent.Close();
mSystemLayer = nullptr;
+ return CHIP_NO_ERROR;
}
void WatchableEventManager::Signal()
@@ -125,7 +126,7 @@
return FD_ISSET(fd, &mRequest.mReadSet) || FD_ISSET(fd, &mRequest.mWriteSet) || FD_ISSET(fd, &mRequest.mErrorSet);
}
-void WatchableEventManager::Set(int fd, fd_set * fds)
+CHIP_ERROR WatchableEventManager::Set(int fd, fd_set * fds)
{
FD_SET(fd, fds);
if (fd > mMaxFd)
@@ -134,9 +135,10 @@
}
// Wake the thread calling select so that it starts selecting on the new socket.
Signal();
+ return CHIP_NO_ERROR;
}
-void WatchableEventManager::Clear(int fd, fd_set * fds)
+CHIP_ERROR WatchableEventManager::Clear(int fd, fd_set * fds)
{
FD_CLR(fd, fds);
if (fd == mMaxFd)
@@ -145,6 +147,7 @@
}
// Wake the thread calling select so that it starts selecting on the new socket.
Signal();
+ return CHIP_NO_ERROR;
}
void WatchableEventManager::Reset(int fd)
diff --git a/src/system/WatchableEventManagerSelect.h b/src/system/WatchableEventManagerSelect.h
index a7bc285..2b12397 100644
--- a/src/system/WatchableEventManagerSelect.h
+++ b/src/system/WatchableEventManagerSelect.h
@@ -41,8 +41,8 @@
class WatchableEventManager
{
public:
- void Init(System::Layer & systemLayer);
- void Shutdown();
+ CHIP_ERROR Init(System::Layer & systemLayer);
+ CHIP_ERROR Shutdown();
void Signal();
void EventLoopBegins() {}
@@ -59,8 +59,8 @@
protected:
friend class WatchableSocket;
- void Set(int fd, fd_set * fds);
- void Clear(int fd, fd_set * fds);
+ CHIP_ERROR Set(int fd, fd_set * fds);
+ CHIP_ERROR Clear(int fd, fd_set * fds);
Layer * mSystemLayer = nullptr;
WatchableSocket * mAttachedSockets = nullptr;
diff --git a/src/system/WatchableSocket.h b/src/system/WatchableSocket.h
index 32ed69a..73615e0 100644
--- a/src/system/WatchableSocket.h
+++ b/src/system/WatchableSocket.h
@@ -27,9 +27,13 @@
#if CHIP_SYSTEM_CONFIG_USE_SOCKETS
+#include <errno.h>
#include <unistd.h>
+#include <core/CHIPError.h>
#include <support/BitFlags.h>
+#include <support/CodeUtils.h>
+#include <system/SystemError.h>
namespace chip {
@@ -57,12 +61,12 @@
* and provide the following methods, which are invoked by the corresponding WatchableSocketBasis functions:
*
* void OnInit()
- * void OnAttach()
- * void OnClose()
- * void OnRequestCallbackOnPendingRead()
- * void OnRequestCallbackOnPendingWrite()
- * void OnClearCallbackOnPendingRead()
- * void OnClearCallbackOnPendingWrite()
+ * CHIP_ERROR OnAttach()
+ * CHIP_ERROR OnRelease()
+ * CHIP_ERROR OnRequestCallbackOnPendingRead()
+ * CHIP_ERROR OnRequestCallbackOnPendingWrite()
+ * CHIP_ERROR OnClearCallbackOnPendingRead()
+ * CHIP_ERROR OnClearCallbackOnPendingWrite()
*
*/
class WatchableSocket;
@@ -96,16 +100,14 @@
*
* @param[in] manager Reference to shared socket-event state (which must already have been initialized).
*/
- Impl & Init(WatchableEventManager & manager)
+ void Init(WatchableEventManager & manager)
{
mFD = kInvalidFd;
mPendingIO.ClearAll();
- mCallback = nullptr;
- mCallbackData = 0;
- mSharedState = &manager;
- Impl * const impl = static_cast<Impl *>(this);
- impl->OnInit();
- return *impl;
+ mCallback = nullptr;
+ mCallbackData = 0;
+ mSharedState = &manager;
+ static_cast<Impl *>(this)->OnInit();
}
/**
@@ -113,12 +115,10 @@
*
* @param[in] fd An open file descriptor.
*/
- Impl & Attach(int fd)
+ CHIP_ERROR Attach(int fd)
{
- mFD = fd;
- Impl * const impl = static_cast<Impl *>(this);
- impl->OnAttach();
- return *impl;
+ mFD = fd;
+ return static_cast<Impl *>(this)->OnAttach();
}
/**
@@ -128,7 +128,7 @@
*/
int ReleaseFD()
{
- static_cast<Impl *>(this)->OnClose();
+ static_cast<Impl *>(this)->OnRelease();
const int fd = mFD;
mFD = kInvalidFd;
return fd;
@@ -136,10 +136,8 @@
/**
* Close the associated file descriptor.
- *
- * @returns the return value of `close(2)`.
*/
- int Close() { return close(ReleaseFD()); }
+ void Close() { VerifyOrDie(close(ReleaseFD()) == 0); }
/**
* Test whether there is an associated open file descriptor.
@@ -154,48 +152,25 @@
/**
* Indicate that the socket-event system should invoke the registered callback when the file descriptor is ready to read.
*/
- Impl & RequestCallbackOnPendingRead(bool request = true)
- {
- Impl * const impl = static_cast<Impl *>(this);
- if (request)
- {
- impl->OnRequestCallbackOnPendingRead();
- }
- return *impl;
- }
+ CHIP_ERROR RequestCallbackOnPendingRead() { return static_cast<Impl *>(this)->OnRequestCallbackOnPendingRead(); }
/**
* Indicate that the socket-event system should invoke the registered callback when the file descriptor is ready to write.
*/
- Impl & RequestCallbackOnPendingWrite(bool request = true)
+ CHIP_ERROR RequestCallbackOnPendingWrite(bool request = true)
{
- Impl * const impl = static_cast<Impl *>(this);
- if (request)
- {
- impl->OnRequestCallbackOnPendingWrite();
- }
- return *impl;
+ return static_cast<Impl *>(this)->OnRequestCallbackOnPendingWrite();
}
/**
* Indicate that the socket-event system need not invoke the registered callback when the file descriptor is ready to read.
*/
- Impl & ClearCallbackOnPendingRead()
- {
- Impl * const impl = static_cast<Impl *>(this);
- impl->OnClearCallbackOnPendingRead();
- return *impl;
- }
+ CHIP_ERROR ClearCallbackOnPendingRead() { return static_cast<Impl *>(this)->OnClearCallbackOnPendingRead(); }
/**
* Indicate that the socket-event system need not invoke the registered callback when the file descriptor is ready to write.
*/
- Impl & ClearCallbackOnPendingWrite()
- {
- Impl * const impl = static_cast<Impl *>(this);
- impl->OnClearCallbackOnPendingWrite();
- return *impl;
- }
+ CHIP_ERROR ClearCallbackOnPendingWrite() { return static_cast<Impl *>(this)->OnClearCallbackOnPendingWrite(); }
/**
* The callback is passed a reference to the WatchableSocket for which the requested event(s) are ready.
@@ -210,11 +185,10 @@
* @param[in] callback Function invoked when event(s) are ready.
* @param[in] data Arbitrary data accessible within a callback function.
*/
- Impl & SetCallback(Callback callback, intptr_t data)
+ void SetCallback(Callback callback, intptr_t data)
{
mCallback = callback;
mCallbackData = data;
- return *static_cast<Impl *>(this);
}
/**
diff --git a/src/system/WatchableSocketLibevent.cpp b/src/system/WatchableSocketLibevent.cpp
index 0913c97..f25213e 100644
--- a/src/system/WatchableSocketLibevent.cpp
+++ b/src/system/WatchableSocketLibevent.cpp
@@ -22,6 +22,7 @@
#include <platform/CHIPDeviceBuildConfig.h>
#include <support/CodeUtils.h>
+#include <system/SystemError.h>
#include <system/SystemLayer.h>
#include <system/WatchableEventManager.h>
#include <system/WatchableSocket.h>
@@ -35,38 +36,42 @@
mActiveNext = nullptr;
}
-void WatchableSocket::OnAttach()
+CHIP_ERROR WatchableSocket::OnAttach()
{
- evutil_make_socket_nonblocking(mFD);
+ VerifyOrReturnError(evutil_make_socket_nonblocking(mFD) == 0, MapErrorPOSIX(errno));
+ return CHIP_NO_ERROR;
}
-void WatchableSocket::OnClose()
+CHIP_ERROR WatchableSocket::OnRelease()
{
- UpdateWatch(0);
+ CHIP_ERROR status = UpdateWatch(0);
mSharedState->RemoveFromQueueIfPresent(this);
+ return status;
}
-void WatchableSocket::SetWatch(short eventFlags)
+CHIP_ERROR WatchableSocket::SetWatch(short eventFlags)
{
const short oldFlags = mEvent ? event_get_events(mEvent) : 0;
const short newFlags = static_cast<short>(EV_PERSIST | oldFlags | eventFlags);
if (oldFlags != newFlags)
{
- UpdateWatch(newFlags);
+ return UpdateWatch(newFlags);
}
+ return CHIP_NO_ERROR;
}
-void WatchableSocket::ClearWatch(short eventFlags)
+CHIP_ERROR WatchableSocket::ClearWatch(short eventFlags)
{
const short oldFlags = mEvent ? event_get_events(mEvent) : 0;
const short newFlags = static_cast<short>(EV_PERSIST | (oldFlags & ~eventFlags));
if (oldFlags != newFlags)
{
- UpdateWatch(newFlags);
+ return UpdateWatch(newFlags);
}
+ return CHIP_NO_ERROR;
}
-void WatchableSocket::UpdateWatch(short eventFlags)
+CHIP_ERROR WatchableSocket::UpdateWatch(short eventFlags)
{
if (mEvent)
{
@@ -78,8 +83,10 @@
{
event_base * const base = mSharedState->mEventBase;
mEvent = event_new(base, mFD, eventFlags, WatchableEventManager::LibeventCallbackHandler, this);
- event_add(mEvent, nullptr);
+ VerifyOrReturnError(mEvent != nullptr, CHIP_ERROR_NO_MEMORY);
+ VerifyOrReturnError(event_add(mEvent, nullptr) == 0, CHIP_ERROR_INTERNAL);
}
+ return CHIP_NO_ERROR;
}
} // namespace System
diff --git a/src/system/WatchableSocketLibevent.h b/src/system/WatchableSocketLibevent.h
index be2448a..8959210 100644
--- a/src/system/WatchableSocketLibevent.h
+++ b/src/system/WatchableSocketLibevent.h
@@ -39,19 +39,19 @@
{
public:
void OnInit();
- void OnAttach();
- void OnClose();
- void OnRequestCallbackOnPendingRead() { SetWatch(EV_READ); }
- void OnRequestCallbackOnPendingWrite() { SetWatch(EV_WRITE); }
- void OnClearCallbackOnPendingRead() { ClearWatch(EV_READ); }
- void OnClearCallbackOnPendingWrite() { ClearWatch(EV_WRITE); }
+ CHIP_ERROR OnAttach();
+ CHIP_ERROR OnRelease();
+ CHIP_ERROR OnRequestCallbackOnPendingRead() { return SetWatch(EV_READ); }
+ CHIP_ERROR OnRequestCallbackOnPendingWrite() { return SetWatch(EV_WRITE); }
+ CHIP_ERROR OnClearCallbackOnPendingRead() { return ClearWatch(EV_READ); }
+ CHIP_ERROR OnClearCallbackOnPendingWrite() { return ClearWatch(EV_WRITE); }
private:
friend class WatchableEventManager;
- void SetWatch(short eventFlags);
- void ClearWatch(short eventFlags);
- void UpdateWatch(short eventFlags);
+ CHIP_ERROR SetWatch(short eventFlags);
+ CHIP_ERROR ClearWatch(short eventFlags);
+ CHIP_ERROR UpdateWatch(short eventFlags);
WatchableSocket * mActiveNext; ///< Next element in the list of sockets activated by libevent.
struct event * mEvent; ///< libevent state.
diff --git a/src/system/WatchableSocketSelect.cpp b/src/system/WatchableSocketSelect.cpp
index 04f8dbb..e418493 100644
--- a/src/system/WatchableSocketSelect.cpp
+++ b/src/system/WatchableSocketSelect.cpp
@@ -32,18 +32,19 @@
namespace chip {
namespace System {
-void WatchableSocket::OnAttach()
+CHIP_ERROR WatchableSocket::OnAttach()
{
mSharedState->Reset(mFD);
- VerifyOrDie(mAttachedNext == nullptr);
+ VerifyOrReturnError(mAttachedNext == nullptr, CHIP_ERROR_INCORRECT_STATE);
mAttachedNext = mSharedState->mAttachedSockets;
mSharedState->mAttachedSockets = this;
+ return CHIP_NO_ERROR;
}
-void WatchableSocket::OnClose()
+CHIP_ERROR WatchableSocket::OnRelease()
{
- VerifyOrDie(mFD >= 0);
+ VerifyOrReturnError(mFD >= 0, CHIP_ERROR_INCORRECT_STATE);
mSharedState->Reset(mFD);
WatchableSocket ** pp = &mSharedState->mAttachedSockets;
@@ -57,30 +58,29 @@
pp = &(*pp)->mAttachedNext;
}
-#if CHIP_SYSTEM_CONFIG_USE_SOCKETS || CHIP_SYSTEM_CONFIG_USE_NETWORK_FRAMEWORK
// Wake the thread calling select so that it stops selecting on the socket.
mSharedState->Signal();
-#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS || CHIP_SYSTEM_CONFIG_USE_NETWORK_FRAMEWORK
+ return CHIP_NO_ERROR;
}
-void WatchableSocket::OnRequestCallbackOnPendingRead()
+CHIP_ERROR WatchableSocket::OnRequestCallbackOnPendingRead()
{
- mSharedState->Set(mFD, &mSharedState->mRequest.mReadSet);
+ return mSharedState->Set(mFD, &mSharedState->mRequest.mReadSet);
}
-void WatchableSocket::OnRequestCallbackOnPendingWrite()
+CHIP_ERROR WatchableSocket::OnRequestCallbackOnPendingWrite()
{
- mSharedState->Set(mFD, &mSharedState->mRequest.mWriteSet);
+ return mSharedState->Set(mFD, &mSharedState->mRequest.mWriteSet);
}
-void WatchableSocket::OnClearCallbackOnPendingRead()
+CHIP_ERROR WatchableSocket::OnClearCallbackOnPendingRead()
{
- mSharedState->Clear(mFD, &mSharedState->mRequest.mReadSet);
+ return mSharedState->Clear(mFD, &mSharedState->mRequest.mReadSet);
}
-void WatchableSocket::OnClearCallbackOnPendingWrite()
+CHIP_ERROR WatchableSocket::OnClearCallbackOnPendingWrite()
{
- mSharedState->Clear(mFD, &mSharedState->mRequest.mWriteSet);
+ return mSharedState->Clear(mFD, &mSharedState->mRequest.mWriteSet);
}
/**
diff --git a/src/system/WatchableSocketSelect.h b/src/system/WatchableSocketSelect.h
index 266ad7e..2d32f98 100644
--- a/src/system/WatchableSocketSelect.h
+++ b/src/system/WatchableSocketSelect.h
@@ -39,13 +39,13 @@
{
public:
void OnInit() { mAttachedNext = nullptr; }
- void OnAttach();
- void OnClose();
+ CHIP_ERROR OnAttach();
+ CHIP_ERROR OnRelease();
- void OnRequestCallbackOnPendingRead();
- void OnRequestCallbackOnPendingWrite();
- void OnClearCallbackOnPendingRead();
- void OnClearCallbackOnPendingWrite();
+ CHIP_ERROR OnRequestCallbackOnPendingRead();
+ CHIP_ERROR OnRequestCallbackOnPendingWrite();
+ CHIP_ERROR OnClearCallbackOnPendingRead();
+ CHIP_ERROR OnClearCallbackOnPendingWrite();
void SetPendingIO(SocketEvents events) { mPendingIO = events; }
void SetFDs(int & nfds, fd_set * readfds, fd_set * writefds, fd_set * exceptfds);
diff --git a/src/system/tests/TestSystemWakeEvent.cpp b/src/system/tests/TestSystemWakeEvent.cpp
index 4dbfd0c..54d2eb5 100644
--- a/src/system/tests/TestSystemWakeEvent.cpp
+++ b/src/system/tests/TestSystemWakeEvent.cpp
@@ -66,7 +66,7 @@
TestContext()
{
- mWatchableEvents.Init(mSystemLayer);
+ (void) mWatchableEvents.Init(mSystemLayer);
mWakeEvent.Open(mWatchableEvents);
}
~TestContext() { mWakeEvent.Close(); }