@@ -577,7 +577,6 @@ namespace zmq
577
577
class socket_t
578
578
{
579
579
friend class monitor_t ;
580
- friend class poller_t ;
581
580
public:
582
581
inline socket_t (context_t & context_, int type_)
583
582
{
@@ -1019,6 +1018,67 @@ namespace zmq
1019
1018
};
1020
1019
1021
1020
#if defined(ZMQ_BUILD_DRAFT_API) && defined(ZMQ_CPP11) && defined(ZMQ_HAVE_POLLER)
1021
+ template <typename T = void >
1022
+ class base_poller_t
1023
+ {
1024
+ public:
1025
+ void add (zmq::socket_t &socket, short events, T *user_data)
1026
+ {
1027
+ if (0 != zmq_poller_add (poller_ptr.get (), static_cast <void *>(socket), user_data, events))
1028
+ {
1029
+ throw error_t ();
1030
+ }
1031
+ }
1032
+
1033
+ void remove (zmq::socket_t &socket)
1034
+ {
1035
+ if (0 != zmq_poller_remove (poller_ptr.get (), static_cast <void *>(socket)))
1036
+ {
1037
+ throw error_t ();
1038
+ }
1039
+ }
1040
+
1041
+ void modify (zmq::socket_t &socket, short events)
1042
+ {
1043
+ if (0 != zmq_poller_modify (poller_ptr.get (), static_cast <void *>(socket), events))
1044
+ {
1045
+ throw error_t ();
1046
+ }
1047
+ }
1048
+
1049
+ int wait_all (std::vector<zmq_poller_event_t > &poller_events, const std::chrono::microseconds timeout)
1050
+ {
1051
+ int rc = zmq_poller_wait_all (poller_ptr.get (), poller_events.data (),
1052
+ static_cast <int > (poller_events.size ()),
1053
+ static_cast <long >(timeout.count ()));
1054
+ if (rc > 0 )
1055
+ return rc;
1056
+
1057
+ #if ZMQ_VERSION >= ZMQ_MAKE_VERSION(4, 2, 3)
1058
+ if (zmq_errno () == EAGAIN)
1059
+ #else
1060
+ if (zmq_errno () == ETIMEDOUT)
1061
+ #endif
1062
+ return 0 ;
1063
+
1064
+ throw error_t ();
1065
+ }
1066
+ private:
1067
+ std::unique_ptr<void , std::function<void (void *)>> poller_ptr
1068
+ {
1069
+ []() {
1070
+ auto poller_new = zmq_poller_new ();
1071
+ if (poller_new)
1072
+ return poller_new;
1073
+ throw error_t ();
1074
+ }(),
1075
+ [](void *ptr) {
1076
+ int rc = zmq_poller_destroy (&ptr);
1077
+ ZMQ_ASSERT (rc == 0 );
1078
+ }
1079
+ };
1080
+ };
1081
+
1022
1082
class poller_t
1023
1083
{
1024
1084
public:
@@ -1035,33 +1095,35 @@ namespace zmq
1035
1095
1036
1096
void add (zmq::socket_t &socket, short events, handler_t handler)
1037
1097
{
1038
- auto it = std::end (handlers);
1039
- auto inserted = false ;
1040
- std::tie (it, inserted) = handlers.emplace (socket.ptr , std::make_shared<handler_t > (std::move (handler)));
1041
- if (0 == zmq_poller_add (poller_ptr.get (), socket.ptr , inserted && *(it->second ) ? it->second .get () : nullptr , events)) {
1042
- need_rebuild = true ;
1043
- return ;
1098
+ auto it = decltype (handlers)::iterator {};
1099
+ auto inserted = bool {};
1100
+ std::tie (it, inserted) = handlers.emplace (static_cast <void *>(socket), std::make_shared<handler_t > (std::move (handler)));
1101
+ try
1102
+ {
1103
+ base_poller.add (socket, events, inserted && *(it->second ) ? it->second .get () : nullptr );
1104
+ need_rebuild |= inserted;
1105
+ }
1106
+ catch (const zmq::error_t &)
1107
+ {
1108
+ // rollback
1109
+ if (inserted)
1110
+ {
1111
+ handlers.erase (static_cast <void *>(socket));
1112
+ }
1113
+ throw ;
1044
1114
}
1045
- // rollback
1046
- if (inserted)
1047
- handlers.erase (socket.ptr );
1048
- throw error_t ();
1049
1115
}
1050
1116
1051
1117
void remove (zmq::socket_t &socket)
1052
1118
{
1053
- if (0 == zmq_poller_remove (poller_ptr.get (), socket.ptr )) {
1054
- handlers.erase (socket.ptr );
1055
- need_rebuild = true ;
1056
- return ;
1057
- }
1058
- throw error_t ();
1119
+ base_poller.remove (socket);
1120
+ handlers.erase (static_cast <void *>(socket));
1121
+ need_rebuild = true ;
1059
1122
}
1060
1123
1061
1124
void modify (zmq::socket_t &socket, short events)
1062
1125
{
1063
- if (0 != zmq_poller_modify (poller_ptr.get (), socket.ptr , events))
1064
- throw error_t ();
1126
+ base_poller.modify (socket, events);
1065
1127
}
1066
1128
1067
1129
int wait (std::chrono::milliseconds timeout)
@@ -1077,25 +1139,15 @@ namespace zmq
1077
1139
}
1078
1140
need_rebuild = false ;
1079
1141
}
1080
- int rc = zmq_poller_wait_all (poller_ptr.get (), poller_events.data (),
1081
- static_cast <int > (poller_events.size ()),
1082
- static_cast <long >(timeout.count ()));
1083
- if (rc > 0 ) {
1084
- std::for_each (poller_events.begin (), poller_events.begin () + rc,
1142
+ const int count = base_poller.wait_all (poller_events, timeout);
1143
+ if (count != 0 ) {
1144
+ std::for_each (poller_events.begin (), poller_events.begin () + count,
1085
1145
[](zmq_poller_event_t & event) {
1086
1146
if (event.user_data != NULL )
1087
1147
(*reinterpret_cast <handler_t *> (event.user_data )) (event.events );
1088
1148
});
1089
- return rc;
1090
1149
}
1091
- #if ZMQ_VERSION >= ZMQ_MAKE_VERSION(4, 2, 3)
1092
- if (zmq_errno () == EAGAIN)
1093
- #else
1094
- if (zmq_errno () == ETIMEDOUT)
1095
- #endif
1096
- return 0 ;
1097
-
1098
- throw error_t ();
1150
+ return count;
1099
1151
}
1100
1152
1101
1153
bool empty () const
@@ -1109,20 +1161,9 @@ namespace zmq
1109
1161
}
1110
1162
1111
1163
private:
1112
- std::unique_ptr<void , std::function<void (void *)>> poller_ptr
1113
- {
1114
- []() {
1115
- auto poller_new = zmq_poller_new ();
1116
- if (poller_new)
1117
- return poller_new;
1118
- throw error_t ();
1119
- }(),
1120
- [](void *ptr) {
1121
- int rc = zmq_poller_destroy (&ptr);
1122
- ZMQ_ASSERT (rc == 0 );
1123
- }
1124
- };
1125
1164
bool need_rebuild {false };
1165
+
1166
+ base_poller_t <handler_t > base_poller {};
1126
1167
std::unordered_map<void *, std::shared_ptr<handler_t >> handlers {};
1127
1168
std::vector<zmq_poller_event_t > poller_events {};
1128
1169
std::vector<std::shared_ptr<handler_t >> poller_handlers {};
0 commit comments