1414#include " util/async_scope.h"
1515#include " util/error.h"
1616#include " util/object.h"
17+ #include " util/string_or_buffer.h"
1718#include " util/take.h"
1819#include " util/uvdelayed.h"
1920#include " util/uvwork.h"
@@ -102,8 +103,7 @@ Socket::Socket(const Napi::CallbackInfo& info)
102103 return ;
103104 }
104105
105- uv_os_sock_t file_descriptor = 0 ;
106- std::function<void ()> const finalize = nullptr ;
106+ auto file_descriptor = uv_os_sock_t {};
107107
108108 const auto error = [this ]() {
109109 [[maybe_unused]] auto err = zmq_close (socket);
@@ -125,22 +125,27 @@ Socket::Socket(const Napi::CallbackInfo& info)
125125 }
126126#endif
127127
128+ std::function<void ()> finalize = nullptr ;
129+
128130 /* Currently only some DRAFT sockets are threadsafe. */
129131 if (thread_safe) {
130132#ifdef ZMQ_HAS_POLLABLE_THREAD_SAFE
131133 /* Threadsafe sockets do not expose an FD we can integrate into the
132134 event loop, so we have to construct one by creating a zmq_poller. */
133- auto poll = zmq_poller_new ();
135+ auto * poll = zmq_poller_new ();
134136 if (poll == nullptr ) {
135137 ErrnoException (Env (), zmq_errno ()).ThrowAsJavaScriptException ();
136138 error ();
137139 }
138140
139141 /* Callback to free the underlying poller. Move the poller to transfer
140142 ownership after the constructor has completed. */
141- finalize = [=]() mutable {
142- [[maybe_unused]] auto err = zmq_poller_destroy (&poll);
143- assert (err == 0 );
143+ finalize = [poll]() mutable {
144+ if (poll != nullptr ) {
145+ [[maybe_unused]] auto err = zmq_poller_destroy (&poll);
146+ assert (err == 0 );
147+ poll = nullptr ;
148+ }
144149 };
145150
146151 if (zmq_poller_add (poll, socket, nullptr , ZMQ_POLLIN | ZMQ_POLLOUT) < 0 ) {
@@ -149,7 +154,7 @@ Socket::Socket(const Napi::CallbackInfo& info)
149154 error ();
150155 }
151156
152- if (zmq_poller_fd (poll, &fd ) < 0 ) {
157+ if (zmq_poller_fd (poll, &file_descriptor ) < 0 ) {
153158 ErrnoException (Env (), zmq_errno ()).ThrowAsJavaScriptException ();
154159 finalize ();
155160 error ();
@@ -327,17 +332,17 @@ void Socket::Receive(const Napi::Promise::Deferred& res) {
327332 switch (type) {
328333 case ZMQ_SERVER: {
329334 auto meta = Napi::Object::New (Env ());
330- meta.Set (" routingId" , zmq_msg_routing_id (part));
331- list[i ++] = meta;
335+ meta.Set (" routingId" , zmq_msg_routing_id (part. get () ));
336+ list[i_part ++] = meta;
332337 break ;
333338 }
334339
335340 case ZMQ_DISH: {
336341 auto meta = Napi::Object::New (Env ());
337- auto data = zmq_msg_group (part);
342+ const auto * data = zmq_msg_group (part. get () );
338343 auto length = strnlen (data, ZMQ_GROUP_MAX_LENGTH);
339344 meta.Set (" group" , Napi::Buffer<char >::Copy (Env (), data, length));
340- list[i ++] = meta;
345+ list[i_part ++] = meta;
341346 break ;
342347 }
343348 }
@@ -610,7 +615,9 @@ Napi::Value Socket::Send(const Napi::CallbackInfo& info) {
610615 Arg::Required<Arg::Object>(" Options must be an object" ),
611616 };
612617
613- if (args.ThrowIfInvalid (info)) return Env ().Undefined ();
618+ if (args.ThrowIfInvalid (info)) {
619+ return Env ().Undefined ();
620+ }
614621
615622 break ;
616623 }
@@ -748,24 +755,20 @@ Napi::Value Socket::Receive(const Napi::CallbackInfo& info) {
748755
749756void Socket::Join ([[maybe_unused]] const Napi::CallbackInfo& info) {
750757#ifdef ZMQ_HAS_POLLABLE_THREAD_SAFE
751- Arg::Validator args{
752- Arg::Required<Arg::String, Arg::Buffer>(" Group must be a string or buffer" ),
753- };
758+ for (size_t i_value = 0 ; i_value < info.Length (); ++i_value) {
759+ const auto & value = info[i_value];
760+ this ->JoinElement (value);
761+ }
762+ #endif
763+ }
754764
755- if (args.ThrowIfInvalid (info)) return ;
765+ void Socket::JoinElement ([[maybe_unused]] const Napi::Value& value) {
766+ #ifdef ZMQ_HAS_POLLABLE_THREAD_SAFE
767+ if (!ValidateOpen ()) {
768+ return ;
769+ }
756770
757- if (!ValidateOpen ()) return ;
758-
759- auto str = [&]() {
760- if (info[0 ].IsString ()) {
761- return std::string (info[0 ].As <Napi::String>());
762- } else {
763- Napi::Object buf = info[0 ].As <Napi::Object>();
764- auto length = buf.As <Napi::Buffer<char >>().Length ();
765- auto value = buf.As <Napi::Buffer<char >>().Data ();
766- return std::string (value, length);
767- }
768- }();
771+ const auto str = convert_string_or_buffer (value);
769772
770773 if (zmq_join (socket, str.c_str ()) < 0 ) {
771774 ErrnoException (Env (), zmq_errno ()).ThrowAsJavaScriptException ();
@@ -776,24 +779,20 @@ void Socket::Join([[maybe_unused]] const Napi::CallbackInfo& info) {
776779
777780void Socket::Leave ([[maybe_unused]] const Napi::CallbackInfo& info) {
778781#ifdef ZMQ_HAS_POLLABLE_THREAD_SAFE
779- Arg::Validator args{
780- Arg::Required<Arg::String, Arg::Buffer>(" Group must be a string or buffer" ),
781- };
782-
783- if (args.ThrowIfInvalid (info)) return ;
782+ for (size_t i_value = 0 ; i_value < info.Length (); ++i_value) {
783+ const auto & value = info[i_value];
784+ this ->LeaveElement (value);
785+ }
786+ #endif
787+ }
784788
785- if (!ValidateOpen ()) return ;
789+ void Socket::LeaveElement ([[maybe_unused]] const Napi::Value& value) {
790+ #ifdef ZMQ_HAS_POLLABLE_THREAD_SAFE
791+ if (!ValidateOpen ()) {
792+ return ;
793+ }
786794
787- auto str = [&]() {
788- if (info[0 ].IsString ()) {
789- return std::string (info[0 ].As <Napi::String>());
790- } else {
791- Napi::Object buf = info[0 ].As <Napi::Object>();
792- auto length = buf.As <Napi::Buffer<char >>().Length ();
793- auto value = buf.As <Napi::Buffer<char >>().Data ();
794- return std::string (value, length);
795- }
796- }();
795+ const auto str = convert_string_or_buffer (value);
797796
798797 if (zmq_leave (socket, str.c_str ()) < 0 ) {
799798 ErrnoException (Env (), zmq_errno ()).ThrowAsJavaScriptException ();
0 commit comments