diff --git a/README.md b/README.md index 13ab5dd76..24bbb320b 100644 --- a/README.md +++ b/README.md @@ -34,57 +34,57 @@ **API v3 Summary** * zactor - simple actor framework -* zauth - authentication for ZeroMQ security mechanisms -* zbeacon - LAN discovery and presence -* zcert - work with CURVE security certificates -* zcertstore - work with CURVE security certificate stores -* zchunk - work with memory chunks -* zclock - millisecond clocks and delays -* zconfig - work with config files written in rfc.zeromq.org/spec:4/ZPL. -* zdigest - provides hashing functions (SHA-1 at present) -* zdir - work with file-system directories -* zdir_patch - work with directory patches -* zfile - provides methods to work with files in a portable fashion. -* zframe - working with single message frames -* zgossip - decentralized configuration management -* zhash - simple generic hash container -* zhashx - extended generic hash container -* ziflist - list of network interfaces available on system -* zlist - simple generic list container -* zlistx - extended generic list container -* zloop - event-driven reactor -* zmonitor - socket event monitor -* zmsg - working with multipart messages -* zpoller - trivial socket poller class -* zproc - process configuration and status -* zproxy - run a steerable proxy in the background -* zrex - work with regular expressions -* zsock - high-level socket API that hides libzmq contexts and sockets -* zstr - sending and receiving strings -* zsys - system-level methods -* ztimerset - timer set -* ztrie - simple trie for tokenizable strings -* zuuid - UUID support class - -**Error Handling** - -**CZMQ Actors** - -**Under the Hood** - -**Adding a New Class** - -**Documentation** - -**Development** - -**Porting CZMQ** - -**Hints to Contributors** - -**Code Generation** - -**This Document** +* zauth - authentication for ZeroMQ security mechanisms +* zbeacon - LAN discovery and presence +* zcert - work with CURVE security certificates +* zcertstore - work with CURVE security certificate stores +* zchunk - work with memory chunks +* zclock - millisecond clocks and delays +* zconfig - work with config files written in rfc.zeromq.org/spec:4/ZPL. +* zdigest - provides hashing functions (SHA-1 at present) +* zdir - work with file-system directories +* zdir_patch - work with directory patches +* zfile - provides methods to work with files in a portable fashion. +* zframe - working with single message frames +* zgossip - decentralized configuration management +* zhash - simple generic hash container +* zhashx - extended generic hash container +* ziflist - list of network interfaces available on system +* zlist - simple generic list container +* zlistx - extended generic list container +* zloop - event-driven reactor +* zmonitor - socket event monitor +* zmsg - working with multipart messages +* zpoller - trivial socket poller class +* zproc - process configuration and status +* zproxy - run a steerable proxy in the background +* zrex - work with regular expressions +* zsock - high-level socket API that hides libzmq contexts and sockets +* zstr - sending and receiving strings +* zsys - system-level methods +* ztimerset - timer set +* ztrie - simple trie for tokenizable strings +* zuuid - UUID support class + +**Error Handling** + +**CZMQ Actors** + +**Under the Hood** + +**Adding a New Class** + +**Documentation** + +**Development** + +**Porting CZMQ** + +**Hints to Contributors** + +**Code Generation** + +**This Document** ## Overview @@ -301,7 +301,7 @@ zmsg, zstr, and zpoller. (zloop somehow escaped and needs catching.) An actor function MUST call zsock_signal (pipe) when initialized and MUST listen to pipe and exit on $TERM command. -Please add @discuss section in ../src/zactor.c. +Please add '@discuss' section in './../src/zactor.c'. This is the class interface: @@ -352,6 +352,7 @@ This is the class interface: zactor_test (bool verbose); ``` +Please add '@interface' section in './../src/zactor.c'. This is the class self test code: @@ -363,9 +364,13 @@ This is the class self test code: assert (streq (string, "This is a string")); free (string); zactor_destroy (&actor); + + #if defined (__WINDOWS__) + zsys_shutdown(); + #endif ``` - + #### zauth - authentication for ZeroMQ security mechanisms A zauth actor takes over authentication for all incoming connections in @@ -451,6 +456,7 @@ This is the class interface: CZMQ_EXPORT void zauth_test (bool verbose); ``` +Please add '@interface' section in './../src/zauth.c'. This is the class self test code: @@ -621,9 +627,15 @@ This is the class self test code: assert (dir); zdir_remove (dir, true); zdir_destroy (&dir); + #endif + + #if defined (__WINDOWS__) + zsys_shutdown(); + #endif + ``` - + #### zbeacon - LAN discovery and presence The zbeacon class implements a peer-to-peer discovery service for local @@ -698,6 +710,7 @@ This is the class interface: CZMQ_EXPORT void zbeacon_test (bool verbose); ``` +Please add '@interface' section in './../src/zbeacon.c'. This is the class self test code: @@ -809,9 +822,13 @@ This is the class self test code: zactor_destroy (&node1); zactor_destroy (&node2); zactor_destroy (&node3); + + #if defined (__WINDOWS__) + zsys_shutdown(); + #endif ``` - + #### zcert - work with CURVE security certificates The zcert class provides a way to create and work with security @@ -929,6 +946,7 @@ This is the class interface: #endif // CZMQ_BUILD_DRAFT_API ``` +Please add '@interface' section in './../src/zcert.c'. This is the class self test code: @@ -983,9 +1001,13 @@ This is the class self test code: assert (dir); zdir_remove (dir, true); zdir_destroy (&dir); + + #if defined (__WINDOWS__) + zsys_shutdown(); + #endif ``` - + #### zcertstore - work with CURVE security certificate stores To authenticate new clients using the ZeroMQ CURVE security mechanism, @@ -1070,6 +1092,7 @@ This is the class interface: #endif // CZMQ_BUILD_DRAFT_API ``` +Please add '@interface' section in './../src/zcertstore.c'. This is the class self test code: @@ -1118,16 +1141,20 @@ This is the class self test code: assert (dir); zdir_remove (dir, true); zdir_destroy (&dir); + + #if defined (__WINDOWS__) + zsys_shutdown(); + #endif ``` - + #### zchunk - work with memory chunks The zchunk class works with variable sized blobs. Not as efficient as ZeroMQ's messages but they do less weirdness and so are easier to understand. The chunk class has methods to read and write chunks from disk. -Please add @discuss section in ../src/zchunk.c. +Please add '@discuss' section in './../src/zchunk.c'. This is the class interface: @@ -1264,6 +1291,7 @@ This is the class interface: zchunk_test (bool verbose); ``` +Please add '@interface' section in './../src/zchunk.c'. This is the class self test code: @@ -1332,9 +1360,13 @@ This is the class self test code: assert (memcmp (zchunk_data (chunk), "ghij", 4) == 0); zchunk_destroy (©); zchunk_destroy (&chunk); + + #if defined (__WINDOWS__) + zsys_shutdown(); + #endif ``` - + #### zclock - millisecond clocks and delays The zclock class provides essential sleep and system time functions, @@ -1382,6 +1414,7 @@ This is the class interface: zclock_test (bool verbose); ``` +Please add '@interface' section in './../src/zclock.c'. This is the class self test code: @@ -1398,9 +1431,13 @@ This is the class self test code: if (verbose) puts (timestr); free (timestr); + + #if defined (__WINDOWS__) + zsys_shutdown(); + #endif ``` - + #### zconfig - work with config files written in rfc.zeromq.org/spec:4/ZPL. Lets applications load, work with, and save configuration files. @@ -1589,6 +1626,7 @@ This is the class interface: zconfig_test (bool verbose); ``` +Please add '@interface' section in './../src/zconfig.c'. This is the class self test code: @@ -1672,9 +1710,13 @@ This is the class self test code: assert (dir); zdir_remove (dir, true); zdir_destroy (&dir); + + #if defined (__WINDOWS__) + zsys_shutdown(); + #endif ``` - + #### zdigest - provides hashing functions (SHA-1 at present) The zdigest class generates a hash from zchunks of data. The current @@ -1723,6 +1765,7 @@ This is the class interface: zdigest_test (bool verbose); ``` +Please add '@interface' section in './../src/zdigest.c'. This is the class self test code: @@ -1742,9 +1785,13 @@ This is the class self test code: "DEB23807D4FE025E900FE9A9C7D8410C3DDE9671")); zdigest_destroy (&digest); free (buffer); + + #if defined (__WINDOWS__) + zsys_shutdown(); + #endif ``` - + #### zdir - work with file-system directories The zdir class gives access to the file system index. It will load @@ -1752,7 +1799,7 @@ a directory tree (a directory plus all child directories) into a zdir structure and then let you navigate that structure. It exists mainly to wrap non-portable OS functions to do this. -Please add @discuss section in ../src/zdir.c. +Please add '@discuss' section in './../src/zdir.c'. This is the class interface: @@ -1860,6 +1907,7 @@ This is the class interface: zdir_test (bool verbose); ``` +Please add '@interface' section in './../src/zdir.c'. This is the class self test code: @@ -1978,15 +2026,19 @@ This is the class self test code: zdir_t *testdir = zdir_new ("zdir-test-dir", NULL); zdir_remove (testdir, true); zdir_destroy (&testdir); + + #if defined (__WINDOWS__) + zsys_shutdown(); + #endif ``` - + #### zdir_patch - work with directory patches The zdir_patch class works with one patch, which says "create this file" or "delete this file" (referring to a zfile item each time). -Please add @discuss section in ../src/zdir_patch.c. +Please add '@discuss' section in './../src/zdir_patch.c'. This is the class interface: @@ -2039,6 +2091,7 @@ This is the class interface: zdir_patch_test (bool verbose); ``` +Please add '@interface' section in './../src/zdir_patch.c'. This is the class self test code: @@ -2054,9 +2107,13 @@ This is the class self test code: assert (streq (zfile_filename (file, "."), "bilbo")); assert (streq (zdir_patch_vpath (patch), "/bilbo")); zdir_patch_destroy (&patch); + + #if defined (__WINDOWS__) + zsys_shutdown(); + #endif ``` - + #### zfile - provides methods to work with files in a portable fashion. The zfile class provides methods to work with disk files. A file object @@ -2219,6 +2276,7 @@ This is the class interface: CZMQ_EXPORT void zfile_mode_default (void); ``` +Please add '@interface' section in './../src/zfile.c'. This is the class self test code: @@ -2350,9 +2408,16 @@ This is the class self test code: assert (zchunk_streq (chunk, "6789")); zchunk_destroy (&chunk); zfile_remove (file); + zfile_close (file); + zfile_destroy (&file); + + #if defined (__WINDOWS__) + zsys_shutdown(); + #endif + ``` - + #### zframe - working with single message frames The zframe class provides methods to send and receive single message @@ -2363,7 +2428,7 @@ normally destroys the frame, but with the ZFRAME_REUSE flag, you can send the same frame many times. Frames are binary, and this class has no special support for text data. -Please add @discuss section in ../src/zframe.c. +Please add '@discuss' section in './../src/zframe.c'. This is the class interface: @@ -2499,6 +2564,7 @@ This is the class interface: #endif // CZMQ_BUILD_DRAFT_API ``` +Please add '@interface' section in './../src/zframe.c'. This is the class self test code: @@ -2660,9 +2726,13 @@ This is the class self test code: zsock_destroy (&radio); #endif + #if defined (__WINDOWS__) + zsys_shutdown(); + #endif + ``` - + #### zgossip - decentralized configuration management Implements a gossip protocol for decentralized configuration management. @@ -2798,6 +2868,7 @@ This is the class interface: CZMQ_EXPORT void zgossip_test (bool verbose); ``` +Please add '@interface' section in './../src/zgossip.c'. This is the class self test code: @@ -2899,9 +2970,13 @@ This is the class self test code: zactor_destroy (&alpha); zactor_destroy (&beta); + #if defined (__WINDOWS__) + zsys_shutdown(); + #endif + ``` - + #### zhash - simple generic hash container zhash is an expandable hash table container. This is a simple container. @@ -3067,6 +3142,7 @@ This is the class interface: zhash_test (bool verbose); ``` +Please add '@interface' section in './../src/zhash.c'. This is the class self test code: @@ -3231,9 +3307,13 @@ This is the class self test code: assert (streq ((char *) zhash_lookup (hash, "key1"), "This is a string")); assert (streq ((char *) zhash_lookup (hash, "key2"), "Ring a ding ding")); zhash_destroy (&hash); + + #if defined (__WINDOWS__) + zsys_shutdown(); + #endif ``` - + #### zhashx - extended generic hash container zhashx is an extended hash table container with more functionality than @@ -3494,6 +3574,7 @@ This is the class interface: #endif // CZMQ_BUILD_DRAFT_API ``` +Please add '@interface' section in './../src/zhashx.c'. This is the class self test code: @@ -3680,9 +3761,13 @@ This is the class self test code: assert (streq ((char *) zhashx_lookup (hash, "key1"), "This is a string")); assert (streq ((char *) zhashx_lookup (hash, "key2"), "Ring a ding ding")); zhashx_destroy (&hash); + + #if defined (__WINDOWS__) + zsys_shutdown(); + #endif ``` - + #### ziflist - list of network interfaces available on system The ziflist class takes a snapshot of the network interfaces that the @@ -3691,7 +3776,7 @@ mobile devices). The caller can then access the network interface information using an iterator that works like zlistx. Only stores those interfaces with broadcast capability, and ignores the loopback interface. -Please add @discuss section in ../src/ziflist.c. +Please add '@discuss' section in './../src/ziflist.c'. This is the class interface: @@ -3743,6 +3828,7 @@ This is the class interface: ziflist_test (bool verbose); ``` +Please add '@interface' section in './../src/ziflist.c'. This is the class self test code: @@ -3764,9 +3850,13 @@ This is the class self test code: ziflist_reload (iflist); assert (items == ziflist_size (iflist)); ziflist_destroy (&iflist); + + #if defined (__WINDOWS__) + zsys_shutdown(); + #endif ``` - + #### zlist - simple generic list container Provides a generic container implementing a fast singly-linked list. You @@ -3908,6 +3998,7 @@ This is the class interface: zlist_test (bool verbose); ``` +Please add '@interface' section in './../src/zlist.c'. This is the class self test code: @@ -4030,9 +4121,13 @@ This is the class self test code: zlist_destroy (&list); assert (list == NULL); + + #if defined (__WINDOWS__) + zsys_shutdown(); + #endif ``` - + #### zlistx - extended generic list container Provides a generic doubly-linked list container. This container provides @@ -4222,6 +4317,7 @@ This is the class interface: zlistx_test (bool verbose); ``` +Please add '@interface' section in './../src/zlistx.c'. This is the class self test code: @@ -4327,9 +4423,13 @@ This is the class self test code: zlistx_purge (list); zlistx_destroy (&list); + + #if defined (__WINDOWS__) + zsys_shutdown(); + #endif ``` - + #### zloop - event-driven reactor The zloop class provides an event-driven reactor pattern. The reactor @@ -4337,7 +4437,7 @@ handles zmq_pollitem_t items (pollers or writers, sockets or fds), and once-off or repeated timers. Its resolution is 1 msec. It uses a tickless timer to reduce CPU interrupts in inactive processes. -Please add @discuss section in ../src/zloop.c. +Please add '@discuss' section in './../src/zloop.c'. This is the class interface: @@ -4472,6 +4572,7 @@ This is the class interface: zloop_test (bool verbose); ``` +Please add '@interface' section in './../src/zloop.c'. This is the class self test code: @@ -4537,9 +4638,13 @@ This is the class self test code: zsock_destroy (&input); zsock_destroy (&output); + + #if defined (__WINDOWS__) + zsys_shutdown(); + #endif ``` - + #### zmonitor - socket event monitor The zmonitor actor provides an API for obtaining socket events such as @@ -4601,6 +4706,7 @@ This is the class interface: CZMQ_EXPORT void zmonitor_test (bool verbose); ``` +Please add '@interface' section in './../src/zmonitor.c'. This is the class self test code: @@ -4612,6 +4718,9 @@ This is the class self test code: if (verbose) zstr_sendx (clientmon, "VERBOSE", NULL); zstr_sendx (clientmon, "LISTEN", "LISTENING", "ACCEPTED", NULL); + #if defined (ZMQ_EVENT_HANDSHAKE_SUCCEED) + zstr_sendx (clientmon, "LISTEN", "HANDSHAKE_SUCCEED", NULL); + #endif zstr_sendx (clientmon, "START", NULL); zsock_wait (clientmon); @@ -4639,15 +4748,22 @@ This is the class self test code: // Check client accepted connection s_assert_event (clientmon, "ACCEPTED"); + #if defined (ZMQ_EVENT_HANDSHAKE_SUCCEED) + s_assert_event (clientmon, "HANDSHAKE_SUCCEED"); + #endif zactor_destroy (&clientmon); zactor_destroy (&servermon); zsock_destroy (&client); zsock_destroy (&server); #endif + + #if defined (__WINDOWS__) + zsys_shutdown(); + #endif ``` - + #### zmsg - working with multipart messages The zmsg class provides methods to send and receive multipart messages @@ -4655,7 +4771,7 @@ across ØMQ sockets. This class provides a list-like container interface, with methods to work with the overall container. zmsg_t messages are composed of zero or more zframe_t frames. -Please add @discuss section in ../src/zmsg.c. +Please add '@discuss' section in './../src/zmsg.c'. This is the class interface: @@ -4866,6 +4982,7 @@ This is the class interface: #endif // CZMQ_BUILD_DRAFT_API ``` +Please add '@interface' section in './../src/zmsg.c'. This is the class self test code: @@ -5139,9 +5256,27 @@ This is the class self test code: zsock_destroy (&client); zsock_destroy (&server); #endif + + // Test message length calculation after removal + msg = zmsg_new (); + zmsg_addstr (msg, "One"); + zmsg_addstr (msg, "Two"); + size_t size_before = zmsg_content_size (msg); + frame = zframe_new ("Three", strlen ("Three")); + assert (frame); + zmsg_remove (msg, frame); + size_t size_after = zmsg_content_size (msg); + assert (size_before == size_after); + zframe_destroy (&frame); + zmsg_destroy (&msg); + + #if defined (__WINDOWS__) + zsys_shutdown(); + #endif + ``` - + #### zpoller - trivial socket poller class The zpoller class provides a minimalist interface to ZeroMQ's zmq_poll @@ -5211,6 +5346,7 @@ This is the class interface: zpoller_test (bool verbose); ``` +Please add '@interface' section in './../src/zpoller.c'. This is the class self test code: @@ -5252,6 +5388,11 @@ This is the class self test code: rc = zpoller_remove (poller, sink); assert (rc == 0); + // Removing a non-existent reader shall fail + rc = zpoller_remove (poller, sink); + assert (rc == -1); + assert (errno == EINVAL); + // Check we can poll an FD rc = zsock_connect (bowl, "tcp://127.0.0.1:%d", port_nbr); assert (rc != -1); @@ -5305,14 +5446,18 @@ This is the class self test code: zsock_destroy (&client); zsock_destroy (&server); #endif + + #if defined (__WINDOWS__) + zsys_shutdown(); + #endif ``` - + #### zproc - process configuration and status zproc - process configuration and status -Please add @discuss section in ../src/zproc.c. +Please add '@discuss' section in './../src/zproc.c'. This is the class interface: @@ -5454,12 +5599,13 @@ This is the class interface: #endif // CZMQ_BUILD_DRAFT_API ``` +Please add '@interface' section in './../src/zproc.c'. This is the class self test code: -Please add @selftest section in ../src/zproc.c. +Please add '@selftest' section in './../src/zproc.c'. - + #### zproxy - run a steerable proxy in the background A zproxy actor switches messages between a frontend and a backend socket. @@ -5556,6 +5702,7 @@ This is the class interface: CZMQ_EXPORT void zproxy_test (bool verbose); ``` +Please add '@interface' section in './../src/zproxy.c'. This is the class self test code: @@ -5632,10 +5779,18 @@ This is the class self test code: proxy = zactor_new (zproxy, NULL); assert (proxy); - sink = zsock_new_sub (">ipc://backend", "whatever"); - assert (sink); + #ifdef WIN32 + sink = zsock_new_sub(">inproc://backend", "whatever"); + #else + sink = zsock_new_sub (">ipc://backend", "whatever"); + #endif // WIN32 + assert (sink); - zstr_sendx (proxy, "BACKEND", "XPUB", "ipc://backend", NULL); + #ifdef WIN32 + zstr_sendx (proxy, "BACKEND", "XPUB", "inproc://backend", NULL); + #else + zstr_sendx(proxy, "BACKEND", "XPUB", "ipc://backend", NULL); + #endif zsock_wait (proxy); zsock_destroy(&sink); @@ -5808,9 +5963,13 @@ This is the class self test code: zsys_file_delete (TESTDIR "/mycert.txt"); zsys_dir_delete (TESTDIR); #endif + + #if defined (__WINDOWS__) + zsys_shutdown(); + #endif ``` - + #### zrex - work with regular expressions Wraps a very simple regular expression library (SLRE) as a CZMQ class. @@ -5840,7 +5999,7 @@ Supports this syntax: \xDD Match byte with hex value 0xDD \meta Match one of the meta character: ^$().[*+?\ -Please add @discuss section in ../src/zrex.c. +Please add '@discuss' section in './../src/zrex.c'. This is the class interface: @@ -5900,6 +6059,7 @@ This is the class interface: CZMQ_EXPORT void zrex_test (bool verbose); ``` +Please add '@interface' section in './../src/zrex.c'. This is the class self test code: @@ -5947,9 +6107,13 @@ This is the class self test code: assert (streq (mechanism, "CURVE")); zrex_destroy (&rex); + #if defined (__WINDOWS__) + zsys_shutdown(); + #endif + ``` - + #### zsock - high-level socket API that hides libzmq contexts and sockets The zsock class wraps the libzmq socket handle (a void *) with a proper @@ -5957,7 +6121,7 @@ structure that follows the CLASS rules for construction and destruction. Some zsock methods take a void * "polymorphic" reference, which can be either a zsock_t or a zactor_t reference, or a libzmq void *. -Please add @discuss section in ../src/zsock.c. +Please add '@discuss' section in './../src/zsock.c'. This is the class interface: @@ -7002,6 +7166,7 @@ This is the class interface: #endif // CZMQ_BUILD_DRAFT_API ``` +Please add '@interface' section in './../src/zsock.c'. This is the class self test code: @@ -7368,7 +7533,7 @@ This is the class self test code: ``` - + #### zstr - sending and receiving strings The zstr class provides utility functions for sending and receiving C @@ -7458,6 +7623,7 @@ This is the class interface: #endif // CZMQ_BUILD_DRAFT_API ``` +Please add '@interface' section in './../src/zstr.c'. This is the class self test code: @@ -7541,16 +7707,20 @@ This is the class self test code: zsock_destroy (&client); zsock_destroy (&server); #endif + + #if defined (__WINDOWS__) + zsys_shutdown(); + #endif ``` - + #### zsys - system-level methods The zsys class provides a portable wrapper for system calls. We collect them here to reduce the number of weird #ifdefs in other classes. As far as possible, the bulk of CZMQ classes are fully portable. -Please add @discuss section in ../src/zsys.c. +Please add '@discuss' section in './../src/zsys.c'. This is the class interface: @@ -7571,7 +7741,8 @@ This is the class interface: // Optionally shut down the CZMQ zsys layer; this normally happens automatically // when the process exits; however this call lets you force a shutdown // earlier, avoiding any potential problems with atexit() ordering, especially - // with Windows dlls. + // with Windows DLL builds, where atexit() does not work and zsys_shutdown has + // to be called manually. CZMQ_EXPORT void zsys_shutdown (void); @@ -7923,6 +8094,7 @@ This is the class interface: // Deprecated name for this variable CZMQ_EXPORT extern volatile int zctx_interrupted; ``` +Please add '@interface' section in './../src/zsys.c'. This is the class self test code: @@ -8030,12 +8202,12 @@ This is the class self test code: zsys_close (logger, NULL, 0); ``` - + #### ztimerset - timer set ztimerset - timer set -Please add @discuss section in ../src/ztimerset.c. +Please add '@discuss' section in './../src/ztimerset.c'. This is the class interface: @@ -8101,6 +8273,7 @@ This is the class interface: #endif // CZMQ_BUILD_DRAFT_API ``` +Please add '@interface' section in './../src/ztimerset.c'. This is the class self test code: @@ -8154,9 +8327,13 @@ This is the class self test code: assert (timeout2 > timeout); ztimerset_destroy (&self); + + #if defined (__WINDOWS__) + zsys_shutdown(); + #endif ``` - + #### ztrie - simple trie for tokenizable strings This is a variant of a trie or prefix tree where all the descendants of a @@ -8245,6 +8422,7 @@ This is the class interface: #endif // CZMQ_BUILD_DRAFT_API ``` +Please add '@interface' section in './../src/ztrie.c'. This is the class self test code: @@ -8397,9 +8575,13 @@ This is the class self test code: zstr_free (&data); ztrie_destroy (&self); + + #if defined (__WINDOWS__) + zsys_shutdown(); + #endif ``` - + #### zuuid - UUID support class The zuuid class generates UUIDs and provides methods for working with @@ -8407,7 +8589,7 @@ them. If you build CZMQ with libuuid, on Unix/Linux, it will use that library. On Windows it will use UuidCreate(). Otherwise it will use a random number generator to produce convincing imitations of UUIDs. -Please add @discuss section in ../src/zuuid.c. +Please add '@discuss' section in './../src/zuuid.c'. This is the class interface: @@ -8475,6 +8657,7 @@ This is the class interface: zuuid_test (bool verbose); ``` +Please add '@interface' section in './../src/zuuid.c'. This is the class self test code: @@ -8517,10 +8700,14 @@ This is the class self test code: zuuid_destroy (&uuid); zuuid_destroy (©); + + #if defined (__WINDOWS__) + zsys_shutdown(); + #endif ``` - + ## Error Handling The CZMQ policy is to reduce the error flow to 0/-1 where possible. libzmq still does a lot of errno setting. CZMQ does not do that, as it creates a fuzzy API. Things either work as expected, or they fail, and the application's best strategy is usually to assert on non-zero return codes. @@ -8537,7 +8724,7 @@ There are a few cases where the return value is overloaded to return -1, 0, or o The overall goal with this strategy is robustness, and absolute minimal and predictable expression in the code. You can see that it works: the CZMQ code is generally very simple and clear, with a few exceptions of places where people have used their old C style (we fix these over time). - + ## CZMQ Actors The v2 API had a zthread class that let you create "attached threads" connected to their parent by an inproc:// PIPE socket. In v3 this has been simplified and better wrapped as the zactor class. CZMQ actors are in effect threads with a socket interface. A zactor_t instance works like a socket, and the CZMQ classes that deal with sockets (like zmsg and zpoller) all accept zactor_t references as well as zsock_t and libzmq void * socket handles. @@ -8683,10 +8870,10 @@ To write an actor, use this template. Note that your actor is a single function The selftest code shows how to create, talk to, and destroy an actor. - + ## Under the Hood - + ### Adding a New Class If you define a new CZMQ class `myclass` you need to: @@ -8698,7 +8885,7 @@ If you define a new CZMQ class `myclass` you need to: * Add myclass to 'model/projects.xml` and read model/README.txt. * Add a section to README.txt. - + ### Documentation Man pages are generated from the class header and source files via the doc/mkman tool, and similar functionality in the gitdown tool (http://github.com/imatix/gitdown). The header file for a class must wrap its interface as follows (example is from include/zclock.h): @@ -8737,7 +8924,7 @@ The source file for a class then provides the self test example as follows: The template for man pages is in doc/mkman. - + ### Development CZMQ is developed through a test-driven process that guarantees no memory violations or leaks in the code: @@ -8747,7 +8934,7 @@ CZMQ is developed through a test-driven process that guarantees no memory violat * Run the 'selftest' script, which uses the Valgrind memcheck tool. * Repeat until perfect. - + ### Porting CZMQ When you try CZMQ on an OS that it's not been used on (ever, or for a while), you will hit code that does not compile. In some cases the patches are trivial, in other cases (usually when porting to Windows), the work needed to build equivalent functionality may be non-trivial. In any case, the benefit is that once ported, the functionality is available to all applications. @@ -8758,7 +8945,7 @@ Before attempting to patch code for portability, please read the `czmq_prelude.h * Defining macros that rename exotic library functions to more conventional names: do this in czmq_prelude.h. * Reimplementing specific methods to use a non-standard API: this is typically needed on Windows. Do this in the relevant class, using #ifdefs to properly differentiate code for different platforms. - + ### Hints to Contributors CZMQ is a nice, neat library, and you may not immediately appreciate why. Read the CLASS style guide please, and write your code to make it indistinguishable from the rest of the code in the library. That is the only real criteria for good style: it's invisible. @@ -8769,14 +8956,14 @@ Do read your code after you write it and ask, "Can I make this simpler?" We do u Before opening a pull request read our [contribution guidelines](https://github.com/zeromq/czmq/blob/master/CONTRIBUTING.md). Thanks! - + ### Code Generation We generate the zsockopt class using [GSL](https://github.com/imatix/gsl), using a code generator script in scripts/sockopts.gsl. We also generate the project files. - + ### This Document This document is originally at README.txt and is built using [gitdown](http://github.com/imatix/gitdown). -_This documentation was generated from libczmq/README.txt using [Gitdown](https://github.com/zeromq/gitdown)_ +_This documentation was generated from czmq/README.txt using [Gitdown](https://github.com/zeromq/gitdown)_ diff --git a/include/zsys.h b/include/zsys.h index 200271d92..739cde86d 100644 --- a/include/zsys.h +++ b/include/zsys.h @@ -35,7 +35,8 @@ CZMQ_EXPORT void * // Optionally shut down the CZMQ zsys layer; this normally happens automatically // when the process exits; however this call lets you force a shutdown // earlier, avoiding any potential problems with atexit() ordering, especially -// with Windows dlls. +// with Windows DLL builds, where atexit() does not work and zsys_shutdown has +// to be called manually. CZMQ_EXPORT void zsys_shutdown (void); diff --git a/src/czmq_selftest.c b/src/czmq_selftest.c index b8f5f4582..e450cc419 100644 --- a/src/czmq_selftest.c +++ b/src/czmq_selftest.c @@ -202,10 +202,6 @@ main (int argc, char **argv) else test_runall (verbose); -#if defined (__WINDOWS__) - zsys_shutdown(); -#endif - return 0; } /* diff --git a/src/test_zgossip.c b/src/test_zgossip.c index 976e402c5..1b8285d26 100644 --- a/src/test_zgossip.c +++ b/src/test_zgossip.c @@ -178,5 +178,9 @@ main (int argn, char *argv []) printf ("(100%%) OK\n"); +#if defined (__WINDOWS__) + zsys_shutdown(); +#endif + return 0; } diff --git a/src/zactor.c b/src/zactor.c index f9a9287c7..9a0fe3ac1 100644 --- a/src/zactor.c +++ b/src/zactor.c @@ -284,6 +284,10 @@ zactor_test (bool verbose) assert (streq (string, "This is a string")); free (string); zactor_destroy (&actor); + +#if defined (__WINDOWS__) + zsys_shutdown(); +#endif // @end printf ("OK\n"); diff --git a/src/zarmour.c b/src/zarmour.c index abb100433..50120bb59 100644 --- a/src/zarmour.c +++ b/src/zarmour.c @@ -931,6 +931,10 @@ zarmour_test (bool verbose) #endif zarmour_destroy (&self); + +#if defined (__WINDOWS__) + zsys_shutdown(); +#endif // @end printf ("OK\n"); diff --git a/src/zauth.c b/src/zauth.c index c65627ece..23464e457 100644 --- a/src/zauth.c +++ b/src/zauth.c @@ -755,7 +755,12 @@ zauth_test (bool verbose) assert (dir); zdir_remove (dir, true); zdir_destroy (&dir); - // @end #endif + +#if defined (__WINDOWS__) + zsys_shutdown(); +#endif + + // @end printf ("OK\n"); } diff --git a/src/zbeacon.c b/src/zbeacon.c index 5c3b1f782..12096c71b 100644 --- a/src/zbeacon.c +++ b/src/zbeacon.c @@ -476,6 +476,10 @@ zbeacon_test (bool verbose) zactor_destroy (&node1); zactor_destroy (&node2); zactor_destroy (&node3); + +#if defined (__WINDOWS__) + zsys_shutdown(); +#endif // @end printf ("OK\n"); } diff --git a/src/zcert.c b/src/zcert.c index ff993f06d..c279a00a6 100644 --- a/src/zcert.c +++ b/src/zcert.c @@ -485,6 +485,10 @@ zcert_test (bool verbose) assert (dir); zdir_remove (dir, true); zdir_destroy (&dir); + +#if defined (__WINDOWS__) + zsys_shutdown(); +#endif // @end printf ("OK\n"); diff --git a/src/zcertstore.c b/src/zcertstore.c index 746961a50..94a0d08db 100644 --- a/src/zcertstore.c +++ b/src/zcertstore.c @@ -348,6 +348,10 @@ zcertstore_test (bool verbose) assert (dir); zdir_remove (dir, true); zdir_destroy (&dir); + +#if defined (__WINDOWS__) + zsys_shutdown(); +#endif // @end printf ("OK\n"); } diff --git a/src/zchunk.c b/src/zchunk.c index 867789bb0..b55ea4b30 100644 --- a/src/zchunk.c +++ b/src/zchunk.c @@ -599,6 +599,10 @@ zchunk_test (bool verbose) assert (memcmp (zchunk_data (chunk), "ghij", 4) == 0); zchunk_destroy (©); zchunk_destroy (&chunk); + +#if defined (__WINDOWS__) + zsys_shutdown(); +#endif // @end printf ("OK\n"); diff --git a/src/zclock.c b/src/zclock.c index 14cdc08fa..56ee73708 100644 --- a/src/zclock.c +++ b/src/zclock.c @@ -227,6 +227,10 @@ zclock_test (bool verbose) if (verbose) puts (timestr); free (timestr); + +#if defined (__WINDOWS__) + zsys_shutdown(); +#endif // @end printf ("OK\n"); diff --git a/src/zconfig.c b/src/zconfig.c index 65f1e9f8d..dd82ef2c0 100644 --- a/src/zconfig.c +++ b/src/zconfig.c @@ -1025,6 +1025,10 @@ zconfig_test (bool verbose) assert (dir); zdir_remove (dir, true); zdir_destroy (&dir); + +#if defined (__WINDOWS__) + zsys_shutdown(); +#endif // @end printf ("OK\n"); diff --git a/src/zdigest.c b/src/zdigest.c index 2e73666c5..ecf4cebee 100644 --- a/src/zdigest.c +++ b/src/zdigest.c @@ -153,6 +153,10 @@ zdigest_test (bool verbose) "DEB23807D4FE025E900FE9A9C7D8410C3DDE9671")); zdigest_destroy (&digest); free (buffer); + +#if defined (__WINDOWS__) + zsys_shutdown(); +#endif // @end printf ("OK\n"); diff --git a/src/zdir.c b/src/zdir.c index 4c721589c..c52627864 100644 --- a/src/zdir.c +++ b/src/zdir.c @@ -1044,6 +1044,10 @@ zdir_test (bool verbose) zdir_t *testdir = zdir_new ("zdir-test-dir", NULL); zdir_remove (testdir, true); zdir_destroy (&testdir); + +#if defined (__WINDOWS__) + zsys_shutdown(); +#endif // @end printf ("OK\n"); diff --git a/src/zdir_patch.c b/src/zdir_patch.c index 746eae124..8bf512b2a 100644 --- a/src/zdir_patch.c +++ b/src/zdir_patch.c @@ -204,6 +204,10 @@ zdir_patch_test (bool verbose) assert (streq (zfile_filename (file, "."), "bilbo")); assert (streq (zdir_patch_vpath (patch), "/bilbo")); zdir_patch_destroy (&patch); + +#if defined (__WINDOWS__) + zsys_shutdown(); +#endif // @end printf ("OK\n"); diff --git a/src/zfile.c b/src/zfile.c index 09ee1ba63..1916c4a29 100644 --- a/src/zfile.c +++ b/src/zfile.c @@ -736,9 +736,14 @@ zfile_test (bool verbose) assert (zchunk_streq (chunk, "6789")); zchunk_destroy (&chunk); zfile_remove (file); - // @end zfile_close (file); zfile_destroy (&file); +#if defined (__WINDOWS__) + zsys_shutdown(); +#endif + + // @end + printf ("OK\n"); } diff --git a/src/zframe.c b/src/zframe.c index 35521043b..4ddfe0167 100644 --- a/src/zframe.c +++ b/src/zframe.c @@ -732,6 +732,10 @@ zframe_test (bool verbose) zsock_destroy (&radio); #endif +#if defined (__WINDOWS__) + zsys_shutdown(); +#endif + // @end printf ("OK\n"); } diff --git a/src/zgossip.c b/src/zgossip.c index 2b725be6f..1a19eb808 100644 --- a/src/zgossip.c +++ b/src/zgossip.c @@ -520,6 +520,10 @@ zgossip_test (bool verbose) zactor_destroy (&alpha); zactor_destroy (&beta); +#if defined (__WINDOWS__) + zsys_shutdown(); +#endif + // @end printf ("OK\n"); } diff --git a/src/zgossip_msg.c b/src/zgossip_msg.c index f2c11664e..287383b97 100644 --- a/src/zgossip_msg.c +++ b/src/zgossip_msg.c @@ -678,6 +678,10 @@ zgossip_msg_test (bool verbose) zgossip_msg_destroy (&self); zsock_destroy (&input); zsock_destroy (&output); + +#if defined (__WINDOWS__) + zsys_shutdown(); +#endif // @end printf ("OK\n"); diff --git a/src/zhash.c b/src/zhash.c index 120525dae..9433578a1 100644 --- a/src/zhash.c +++ b/src/zhash.c @@ -946,6 +946,10 @@ zhash_test (bool verbose) assert (streq ((char *) zhash_lookup (hash, "key1"), "This is a string")); assert (streq ((char *) zhash_lookup (hash, "key2"), "Ring a ding ding")); zhash_destroy (&hash); + +#if defined (__WINDOWS__) + zsys_shutdown(); +#endif // @end printf ("OK\n"); diff --git a/src/zhashx.c b/src/zhashx.c index ef442be72..af139a64c 100644 --- a/src/zhashx.c +++ b/src/zhashx.c @@ -1302,6 +1302,10 @@ zhashx_test (bool verbose) assert (streq ((char *) zhashx_lookup (hash, "key1"), "This is a string")); assert (streq ((char *) zhashx_lookup (hash, "key2"), "Ring a ding ding")); zhashx_destroy (&hash); + +#if defined (__WINDOWS__) + zsys_shutdown(); +#endif // @end printf ("OK\n"); diff --git a/src/ziflist.c b/src/ziflist.c index c4d0d0b6f..49798f254 100644 --- a/src/ziflist.c +++ b/src/ziflist.c @@ -385,6 +385,10 @@ ziflist_test (bool verbose) ziflist_reload (iflist); assert (items == ziflist_size (iflist)); ziflist_destroy (&iflist); + +#if defined (__WINDOWS__) + zsys_shutdown(); +#endif // @end printf ("OK\n"); diff --git a/src/zlist.c b/src/zlist.c index e7c55a1b3..e3ce17225 100644 --- a/src/zlist.c +++ b/src/zlist.c @@ -624,6 +624,10 @@ zlist_test (bool verbose) zlist_destroy (&list); assert (list == NULL); + +#if defined (__WINDOWS__) + zsys_shutdown(); +#endif // @end printf ("OK\n"); diff --git a/src/zlistx.c b/src/zlistx.c index 80ac23d4b..d30991cc4 100644 --- a/src/zlistx.c +++ b/src/zlistx.c @@ -743,6 +743,10 @@ zlistx_test (bool verbose) zlistx_purge (list); zlistx_destroy (&list); + +#if defined (__WINDOWS__) + zsys_shutdown(); +#endif // @end printf ("OK\n"); diff --git a/src/zloop.c b/src/zloop.c index e901d56a5..885f6b289 100644 --- a/src/zloop.c +++ b/src/zloop.c @@ -947,6 +947,10 @@ zloop_test (bool verbose) zsock_destroy (&input); zsock_destroy (&output); + +#if defined (__WINDOWS__) + zsys_shutdown(); +#endif // @end printf ("OK\n"); } diff --git a/src/zmonitor.c b/src/zmonitor.c index 227370f6b..b042338d9 100644 --- a/src/zmonitor.c +++ b/src/zmonitor.c @@ -392,6 +392,10 @@ zmonitor_test (bool verbose) zsock_destroy (&client); zsock_destroy (&server); #endif + +#if defined (__WINDOWS__) + zsys_shutdown(); +#endif // @end printf ("OK\n"); } diff --git a/src/zmsg.c b/src/zmsg.c index d17edb63b..29019b8fc 100644 --- a/src/zmsg.c +++ b/src/zmsg.c @@ -1240,6 +1240,10 @@ zmsg_test (bool verbose) zframe_destroy (&frame); zmsg_destroy (&msg); +#if defined (__WINDOWS__) + zsys_shutdown(); +#endif + // @end printf ("OK\n"); } diff --git a/src/zpoller.c b/src/zpoller.c index 89b6e18ef..575fab089 100644 --- a/src/zpoller.c +++ b/src/zpoller.c @@ -387,6 +387,10 @@ zpoller_test (bool verbose) zsock_destroy (&client); zsock_destroy (&server); #endif + +#if defined (__WINDOWS__) + zsys_shutdown(); +#endif // @end printf ("OK\n"); diff --git a/src/zproxy.c b/src/zproxy.c index 29bd58999..ea43fb9cb 100644 --- a/src/zproxy.c +++ b/src/zproxy.c @@ -547,11 +547,11 @@ zproxy_test (bool verbose) proxy = zactor_new (zproxy, NULL); assert (proxy); -#ifdef WIN32 +#ifdef WIN32 sink = zsock_new_sub(">inproc://backend", "whatever"); -#else - sink = zsock_new_sub (">ipc://backend", "whatever"); -#endif // WIN32 +#else + sink = zsock_new_sub (">ipc://backend", "whatever"); +#endif // WIN32 assert (sink); #ifdef WIN32 @@ -731,6 +731,10 @@ zproxy_test (bool verbose) zsys_file_delete (TESTDIR "/mycert.txt"); zsys_dir_delete (TESTDIR); #endif + +#if defined (__WINDOWS__) + zsys_shutdown(); +#endif // @end printf ("OK\n"); } diff --git a/src/zrex.c b/src/zrex.c index 579a114fe..5948f61e8 100644 --- a/src/zrex.c +++ b/src/zrex.c @@ -300,6 +300,10 @@ zrex_test (bool verbose) assert (streq (zrex_hit (rex, 1), "CURVE")); assert (streq (mechanism, "CURVE")); zrex_destroy (&rex); + +#if defined (__WINDOWS__) + zsys_shutdown(); +#endif // @end printf ("OK\n"); diff --git a/src/zsock.c b/src/zsock.c index 582ea69cf..b973e3918 100644 --- a/src/zsock.c +++ b/src/zsock.c @@ -2184,4 +2184,8 @@ zsock_test (bool verbose) // @end printf ("OK\n"); zsock_option_test (verbose); + +#if defined (__WINDOWS__) + zsys_shutdown(); +#endif } diff --git a/src/zstr.c b/src/zstr.c index 7265d203c..2ae5ab0a8 100644 --- a/src/zstr.c +++ b/src/zstr.c @@ -386,6 +386,10 @@ zstr_test (bool verbose) zsock_destroy (&client); zsock_destroy (&server); #endif + +#if defined (__WINDOWS__) + zsys_shutdown(); +#endif // @end printf ("OK\n"); diff --git a/src/zsys.c b/src/zsys.c index a331b1b63..32f1481f6 100644 --- a/src/zsys.c +++ b/src/zsys.c @@ -1881,5 +1881,9 @@ zsys_test (bool verbose) zsys_set_max_msgsz (-1); assert (zsys_max_msgsz () == 2000); +#if defined (__WINDOWS__) + zsys_shutdown(); +#endif + printf ("OK\n"); } diff --git a/src/ztimerset.c b/src/ztimerset.c index 8dcdd47c8..d6bf51b7b 100644 --- a/src/ztimerset.c +++ b/src/ztimerset.c @@ -217,6 +217,10 @@ ztimerset_test (bool verbose) assert (timeout2 > timeout); ztimerset_destroy (&self); + +#if defined (__WINDOWS__) + zsys_shutdown(); +#endif // @end printf ("OK\n"); #endif diff --git a/src/ztrie.c b/src/ztrie.c index f3c91090e..a8b70af9a 100644 --- a/src/ztrie.c +++ b/src/ztrie.c @@ -799,6 +799,10 @@ ztrie_test (bool verbose) zstr_free (&data); ztrie_destroy (&self); + +#if defined (__WINDOWS__) + zsys_shutdown(); +#endif // @end printf ("OK\n"); diff --git a/src/zuuid.c b/src/zuuid.c index 34d09937d..683821d04 100644 --- a/src/zuuid.c +++ b/src/zuuid.c @@ -334,6 +334,10 @@ zuuid_test (bool verbose) zuuid_destroy (&uuid); zuuid_destroy (©); + +#if defined (__WINDOWS__) + zsys_shutdown(); +#endif // @end printf ("OK\n");