PageRenderTime 33ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/tools-zeromq/src/main/java/org/zeromq/ZMQ.java

https://bitbucket.org/mneagul/mosaic-java-platform
Java | 1227 lines | 429 code | 146 blank | 652 comment | 46 complexity | 6259d913415577cc9541d645b557482d MD5 | raw file
Possible License(s): Apache-2.0, GPL-3.0
  1. /*
  2. * #%L
  3. * mosaic-tools-zeromq
  4. * %%
  5. * Copyright (C) 2010 - 2012 Institute e-Austria Timisoara (Romania)
  6. * %%
  7. * This program is free software: you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as
  9. * published by the Free Software Foundation, either version 3 of the
  10. * License, or (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public
  18. * License along with this program. If not, see
  19. * <http://www.gnu.org/licenses/gpl-3.0.html>.
  20. * #L%
  21. */
  22. /*
  23. Copyright (c) 2007-2010 iMatix Corporation
  24. This file is part of 0MQ.
  25. 0MQ is free software; you can redistribute it and/or modify it under
  26. the terms of the Lesser GNU General Public License as published by
  27. the Free Software Foundation; either version 3 of the License, or
  28. (at your option) any later version.
  29. 0MQ is distributed in the hope that it will be useful,
  30. but WITHOUT ANY WARRANTY; without even the implied warranty of
  31. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  32. Lesser GNU General Public License for more details.
  33. You should have received a copy of the Lesser GNU General Public License
  34. along with this program. If not, see <http://www.gnu.org/licenses/>.
  35. */
  36. package org.zeromq;
  37. import java.util.LinkedList;
  38. /**
  39. * ZeroMQ JNI Bindings.
  40. *
  41. * @author Gonzalo Diethelm
  42. *
  43. */
  44. public class ZMQ {
  45. static {
  46. System.loadLibrary ("jzmq");
  47. }
  48. // Values for flags in Socket's send and recv functions.
  49. /**
  50. * Socket flag to indicate a nonblocking send or recv mode.
  51. */
  52. public static final int NOBLOCK = 1;
  53. public static final int DONTWAIT = 1;
  54. /**
  55. * Socket flag to indicate that more message parts are coming.
  56. */
  57. public static final int SNDMORE = 2;
  58. // Socket types, used when creating a Socket.
  59. /**
  60. * Flag to specify a exclusive pair of sockets.
  61. */
  62. public static final int PAIR = 0;
  63. /**
  64. * Flag to specify a PUB socket, receiving side must be a SUB.
  65. */
  66. public static final int PUB = 1;
  67. /**
  68. * Flag to specify the receiving part of the PUB socket.
  69. */
  70. public static final int SUB = 2;
  71. /**
  72. * Flag to specify a REQ socket, receiving side must be a REP.
  73. */
  74. public static final int REQ = 3;
  75. /**
  76. * Flag to specify the receiving part of a REQ socket.
  77. */
  78. public static final int REP = 4;
  79. /**
  80. * Flag to specify a XREQ socket, receiving side must be a XREP.
  81. */
  82. public static final int XREQ = 5;
  83. /**
  84. * Flag to specify the receiving part of a XREQ socket.
  85. */
  86. public static final int XREP = 6;
  87. /**
  88. * Flag to specify the receiving part of a PUSH socket.
  89. */
  90. public static final int PULL = 7;
  91. /**
  92. * Flag to specify a PUSH socket, receiving side must be a PULL.
  93. */
  94. public static final int PUSH = 8;
  95. /**
  96. * Flag to specify a STREAMER device.
  97. */
  98. public static final int STREAMER = 1;
  99. /**
  100. * Flag to specify a FORWARDER device.
  101. */
  102. public static final int FORWARDER = 2;
  103. /**
  104. * Flag to specify a QUEUE device.
  105. */
  106. public static final int QUEUE = 3;
  107. /**
  108. * @see ZMQ#PULL
  109. */
  110. @Deprecated
  111. public static final int UPSTREAM = PULL;
  112. /**
  113. * @see ZMQ#PUSH
  114. */
  115. @Deprecated
  116. public static final int DOWNSTREAM = PUSH;
  117. protected static native int version_full();
  118. protected static native int version_major();
  119. protected static native int version_minor();
  120. protected static native int version_patch();
  121. protected static native int make_version(int major, int minor, int patch);
  122. protected static native long ENOTSUP();
  123. protected static native long EPROTONOSUPPORT();
  124. protected static native long ENOBUFS();
  125. protected static native long ENETDOWN();
  126. protected static native long EADDRINUSE();
  127. protected static native long EADDRNOTAVAIL();
  128. protected static native long ECONNREFUSED();
  129. protected static native long EINPROGRESS();
  130. protected static native long EMTHREAD();
  131. protected static native long EFSM();
  132. protected static native long ENOCOMPATPROTO();
  133. protected static native long ETERM();
  134. /**
  135. * Inner class: Error.
  136. */
  137. public enum Error {
  138. ENOTSUP(ENOTSUP()),
  139. EPROTONOSUPPORT(EPROTONOSUPPORT()),
  140. ENOBUFS(ENOBUFS()),
  141. ENETDOWN(ENETDOWN()),
  142. EADDRINUSE(EADDRINUSE()),
  143. EADDRNOTAVAIL(EADDRNOTAVAIL()),
  144. ECONNREFUSED(ECONNREFUSED()),
  145. EINPROGRESS(EINPROGRESS()),
  146. EMTHREAD(EMTHREAD()),
  147. EFSM(EFSM()),
  148. ENOCOMPATPROTO(ENOCOMPATPROTO()),
  149. ETERM(ETERM());
  150. private final long code;
  151. Error(long code) {
  152. this.code = code;
  153. }
  154. public long getCode() {
  155. return code;
  156. }
  157. public static Error findByCode(int code) {
  158. for (Error e : Error.class.getEnumConstants()) {
  159. if (e.getCode() == code) {
  160. return e;
  161. }
  162. }
  163. throw new IllegalArgumentException("Unknown " + Error.class.getName() + " enum code:" + code);
  164. }
  165. }
  166. /**
  167. * Create a new Context.
  168. *
  169. * @param ioThreads
  170. * Number of threads to use, usually 1 is sufficient for most use cases.
  171. * @return the Context
  172. */
  173. public static Context context (int ioThreads) {
  174. return new Context (ioThreads);
  175. }
  176. /**
  177. * Inner class: Context.
  178. */
  179. public static class Context {
  180. /**
  181. * This is an explicit "destructor". It can be called to ensure the corresponding 0MQ
  182. * Context has been disposed of.
  183. */
  184. public void term () {
  185. finalize ();
  186. }
  187. /**
  188. * Create a new Socket within this context.
  189. *
  190. * @param type
  191. * the socket type.
  192. * @return the newly created Socket.
  193. */
  194. public Socket socket (int type) {
  195. return new Socket (this, type);
  196. }
  197. /**
  198. * Create a new Poller within this context, with a default size.
  199. *
  200. * @return the newly created Poller.
  201. */
  202. public Poller poller () {
  203. return new Poller (this);
  204. }
  205. /**
  206. * Create a new Poller within this context, with a specified initial size.
  207. *
  208. * @param size
  209. * the poller initial size.
  210. * @return the newly created Poller.
  211. */
  212. public Poller poller (int size) {
  213. return new Poller (this, size);
  214. }
  215. /**
  216. * Class constructor.
  217. *
  218. * @param ioThreads
  219. * size of the threads pool to handle I/O operations.
  220. */
  221. protected Context (int ioThreads) {
  222. construct (ioThreads);
  223. }
  224. /** Initialize the JNI interface */
  225. protected native void construct (int ioThreads);
  226. /** Free all resources used by JNI interface. */
  227. @Override
  228. protected native void finalize ();
  229. /**
  230. * Get the underlying context handle. This is private because it is only accessed from JNI,
  231. * where Java access controls are ignored.
  232. *
  233. * @return the internal 0MQ context handle.
  234. */
  235. private long getContextHandle () {
  236. return this.contextHandle;
  237. }
  238. /** Opaque data used by JNI driver. */
  239. private long contextHandle;
  240. }
  241. /**
  242. * Inner class: Socket.
  243. */
  244. public static class Socket {
  245. /**
  246. * This is an explicit "destructor". It can be called to ensure the corresponding 0MQ Socket
  247. * has been disposed of.
  248. */
  249. public void close () {
  250. finalize ();
  251. }
  252. /**
  253. * The 'ZMQ_TYPE option shall retrieve the socket type for the specified
  254. * 'socket'. The socket type is specified at socket creation time and
  255. * cannot be modified afterwards.
  256. *
  257. * @return the socket type.
  258. * @since 2.1.0
  259. */
  260. public long getType () {
  261. if (ZMQ.version_full() < ZMQ.make_version(2, 1, 0))
  262. return -1;
  263. return getLongSockopt (TYPE);
  264. }
  265. /**
  266. * @see #setLinger(long)
  267. *
  268. * @return the linger period.
  269. * @since 2.1.0
  270. */
  271. public long getLinger () {
  272. if (ZMQ.version_full() < ZMQ.make_version(2, 1, 0))
  273. return -1;
  274. return getLongSockopt (LINGER);
  275. }
  276. /**
  277. * @see #setReconnectIVL(long)
  278. *
  279. * @return the reconnectIVL.
  280. * @since 3.0.0
  281. */
  282. public long getReconnectIVL () {
  283. if (ZMQ.version_full() < ZMQ.make_version(3, 0, 0))
  284. return -1;
  285. return getLongSockopt (RECONNECT_IVL);
  286. }
  287. /**
  288. * @see #setBacklog(long)
  289. *
  290. * @return the backlog.
  291. * @since 3.0.0
  292. */
  293. public long getBacklog () {
  294. if (ZMQ.version_full() < ZMQ.make_version(3, 0, 0))
  295. return -1;
  296. return getLongSockopt (BACKLOG);
  297. }
  298. /**
  299. * @see #setReconnectIVLMax(long)
  300. *
  301. * @return the reconnectIVLMax.
  302. * @since 3.0.0
  303. */
  304. public long getReconnectIVLMax () {
  305. if (ZMQ.version_full() < ZMQ.make_version(3, 0, 0))
  306. return -1;
  307. return getLongSockopt (RECONNECT_IVL_MAX);
  308. }
  309. /**
  310. * @see #setMaxMsgSize(long)
  311. *
  312. * @return the maxMsgSize.
  313. * @since 3.0.0
  314. */
  315. public long getMaxMsgSize () {
  316. if (ZMQ.version_full() < ZMQ.make_version(3, 0, 0))
  317. return -1;
  318. return getLongSockopt (MAXMSGSIZE);
  319. }
  320. /**
  321. * @see #setSndHWM(long)
  322. *
  323. * @return the SndHWM.
  324. * @since 3.0.0
  325. */
  326. public long getSndHWM () {
  327. if (ZMQ.version_full() < ZMQ.make_version(3, 0, 0))
  328. return -1;
  329. return getLongSockopt (SNDHWM);
  330. }
  331. /**
  332. * @see #setRcvHWM(long)
  333. *
  334. * @return the recvHWM period.
  335. * @since 3.0.0
  336. */
  337. public long getRcvHWM () {
  338. if (ZMQ.version_full() < ZMQ.make_version(3, 0, 0))
  339. return -1;
  340. return getLongSockopt (RCVHWM);
  341. }
  342. /**
  343. * @see #setHWM(long)
  344. *
  345. * @return the High Water Mark.
  346. */
  347. public long getHWM () {
  348. if (ZMQ.version_full() >= ZMQ.make_version(3, 0, 0))
  349. return -1;
  350. return getLongSockopt (HWM);
  351. }
  352. /**
  353. * @see #setSwap(long)
  354. *
  355. * @return the number of messages to swap at most.
  356. */
  357. public long getSwap () {
  358. if (ZMQ.version_full() >= ZMQ.make_version(3, 0, 0))
  359. return -1;
  360. return getLongSockopt (SWAP);
  361. }
  362. /**
  363. * @see #setAffinity(long)
  364. *
  365. * @return the affinity.
  366. */
  367. public long getAffinity () {
  368. return getLongSockopt (AFFINITY);
  369. }
  370. /**
  371. * @see #setIdentity(byte[])
  372. *
  373. * @return the Identitiy.
  374. */
  375. public byte [] getIdentity () {
  376. return getBytesSockopt (IDENTITY);
  377. }
  378. /**
  379. * @see #setRate(long)
  380. *
  381. * @return the Rate.
  382. */
  383. public long getRate () {
  384. return getLongSockopt (RATE);
  385. }
  386. /**
  387. * @see #setRecoveryInterval(long)
  388. *
  389. * @return the RecoveryIntervall.
  390. */
  391. public long getRecoveryInterval () {
  392. return getLongSockopt (RECOVERY_IVL);
  393. }
  394. /**
  395. * @see #setMulticastLoop(boolean)
  396. *
  397. * @return the Multicast Loop.
  398. */
  399. public boolean hasMulticastLoop () {
  400. if (ZMQ.version_full() >= ZMQ.make_version(3, 0, 0))
  401. return false;
  402. return getLongSockopt (MCAST_LOOP) != 0;
  403. }
  404. /**
  405. * @see #setSendBufferSize(long)
  406. *
  407. * @return the kernel send buffer size.
  408. */
  409. public long getSendBufferSize () {
  410. return getLongSockopt (SNDBUF);
  411. }
  412. /**
  413. * @see #setReceiveBufferSize(long)
  414. *
  415. * @return the kernel receive buffer size.
  416. */
  417. public long getReceiveBufferSize () {
  418. return getLongSockopt (RCVBUF);
  419. }
  420. /**
  421. * The 'ZMQ_RCVMORE' option shall return a boolean value indicating if the multi-part
  422. * message currently being read from the specified 'socket' has more message parts to
  423. * follow. If there are no message parts to follow or if the message currently being read is
  424. * not a multi-part message a value of zero shall be returned. Otherwise, a value of 1 shall
  425. * be returned.
  426. *
  427. * @return true if there are more messages to receive.
  428. */
  429. public boolean hasReceiveMore () {
  430. return getLongSockopt (RCVMORE) != 0;
  431. }
  432. /**
  433. * The 'ZMQ_FD' option shall retrieve file descriptor associated with the 0MQ
  434. * socket. The descriptor can be used to integrate 0MQ socket into an existing
  435. * event loop. It should never be used for anything else than polling -- such as
  436. * reading or writing. The descriptor signals edge-triggered IN event when
  437. * something has happened within the 0MQ socket. It does not necessarily mean that
  438. * the messages can be read or written. Check ZMQ_EVENTS option to find out whether
  439. * the 0MQ socket is readable or writeable.
  440. *
  441. * @return the underlying file descriptor.
  442. * @since 2.1.0
  443. */
  444. public long getFD () {
  445. if (ZMQ.version_full() < ZMQ.make_version(2, 1, 0))
  446. return -1;
  447. return getLongSockopt (FD);
  448. }
  449. /**
  450. * The 'ZMQ_EVENTS' option shall retrieve event flags for the specified socket.
  451. * If a message can be read from the socket ZMQ_POLLIN flag is set. If message can
  452. * be written to the socket ZMQ_POLLOUT flag is set.
  453. *
  454. * @return the mask of outstanding events.
  455. * @since 2.1.0
  456. */
  457. public long getEvents () {
  458. if (ZMQ.version_full() < ZMQ.make_version(2, 1, 0))
  459. return -1;
  460. return getLongSockopt (EVENTS);
  461. }
  462. /**
  463. * The 'ZMQ_LINGER' option shall retrieve the period for pending outbound
  464. * messages to linger in memory after closing the socket. Value of -1 means
  465. * infinite. Pending messages will be kept until they are fully transferred to
  466. * the peer. Value of 0 means that all the pending messages are dropped immediately
  467. * when socket is closed. Positive value means number of milliseconds to keep
  468. * trying to send the pending messages before discarding them.
  469. *
  470. * @param linger
  471. * the linger period.
  472. * @since 2.1.0
  473. */
  474. public void setLinger (long linger) {
  475. if (ZMQ.version_full() < ZMQ.make_version(2, 1, 0))
  476. return;
  477. setLongSockopt (LINGER, linger);
  478. }
  479. /**
  480. * @since 3.0.0
  481. */
  482. public void setReconnectIVL (long reconnectIVL) {
  483. if (ZMQ.version_full() < ZMQ.make_version(3, 0, 0))
  484. return;
  485. setLongSockopt (RECONNECT_IVL, reconnectIVL);
  486. }
  487. /**
  488. * @since 3.0.0
  489. */
  490. public void setBacklog (long backlog) {
  491. if (ZMQ.version_full() < ZMQ.make_version(3, 0, 0))
  492. return;
  493. setLongSockopt (BACKLOG, backlog);
  494. }
  495. /**
  496. * @since 3.0.0
  497. */
  498. public void setReconnectIVLMax (long reconnectIVLMax) {
  499. if (ZMQ.version_full() < ZMQ.make_version(3, 0, 0))
  500. return;
  501. setLongSockopt (RECONNECT_IVL_MAX, reconnectIVLMax);
  502. }
  503. /**
  504. * @since 3.0.0
  505. */
  506. public void setMaxMsgSize (long maxMsgSize) {
  507. if (ZMQ.version_full() < ZMQ.make_version(3, 0, 0))
  508. return;
  509. setLongSockopt (MAXMSGSIZE, maxMsgSize);
  510. }
  511. /**
  512. * @since 3.0.0
  513. */
  514. public void setSndHWM (long sndHWM) {
  515. if (ZMQ.version_full() < ZMQ.make_version(3, 0, 0))
  516. return;
  517. setLongSockopt (SNDHWM, sndHWM);
  518. }
  519. /**
  520. * @since 3.0.0
  521. */
  522. public void setRcvHWM (long rcvHWM) {
  523. if (ZMQ.version_full() < ZMQ.make_version(3, 0, 0))
  524. return;
  525. setLongSockopt (RCVHWM, rcvHWM);
  526. }
  527. /**
  528. * The 'ZMQ_HWM' option shall set the high water mark for the specified 'socket'. The high
  529. * water mark is a hard limit on the maximum number of outstanding messages 0MQ shall queue
  530. * in memory for any single peer that the specified 'socket' is communicating with.
  531. *
  532. * If this limit has been reached the socket shall enter an exceptional state and depending
  533. * on the socket type, 0MQ shall take appropriate action such as blocking or dropping sent
  534. * messages. Refer to the individual socket descriptions in the man page of zmq_socket[3] for
  535. * details on the exact action taken for each socket type.
  536. *
  537. * @param hwm
  538. * the number of messages to queue.
  539. */
  540. public void setHWM (long hwm) {
  541. if (ZMQ.version_full() >= ZMQ.make_version(3, 0, 0))
  542. return;
  543. setLongSockopt (HWM, hwm);
  544. }
  545. /**
  546. * Get the Swap. The 'ZMQ_SWAP' option shall set the disk offload (swap) size for the
  547. * specified 'socket'. A socket which has 'ZMQ_SWAP' set to a non-zero value may exceed its
  548. * high water mark; in this case outstanding messages shall be offloaded to storage on disk
  549. * rather than held in memory.
  550. *
  551. * @param swap
  552. * The value of 'ZMQ_SWAP' defines the maximum size of the swap space in bytes.
  553. */
  554. public void setSwap (long swap) {
  555. if (ZMQ.version_full() >= ZMQ.make_version(3, 0, 0))
  556. return;
  557. setLongSockopt (SWAP, swap);
  558. }
  559. /**
  560. * Get the Affinity. The 'ZMQ_AFFINITY' option shall set the I/O thread affinity for newly
  561. * created connections on the specified 'socket'.
  562. *
  563. * Affinity determines which threads from the 0MQ I/O thread pool associated with the
  564. * socket's _context_ shall handle newly created connections. A value of zero specifies no
  565. * affinity, meaning that work shall be distributed fairly among all 0MQ I/O threads in the
  566. * thread pool. For non-zero values, the lowest bit corresponds to thread 1, second lowest
  567. * bit to thread 2 and so on. For example, a value of 3 specifies that subsequent
  568. * connections on 'socket' shall be handled exclusively by I/O threads 1 and 2.
  569. *
  570. * See also in the man page of zmq_init[3] for details on allocating the number of I/O threads for a
  571. * specific _context_.
  572. *
  573. * @param affinity
  574. * the affinity.
  575. */
  576. public void setAffinity (long affinity) {
  577. setLongSockopt (AFFINITY, affinity);
  578. }
  579. /**
  580. * The 'ZMQ_IDENTITY' option shall set the identity of the specified 'socket'. Socket
  581. * identity determines if existing 0MQ infastructure (_message queues_, _forwarding
  582. * devices_) shall be identified with a specific application and persist across multiple
  583. * runs of the application.
  584. *
  585. * If the socket has no identity, each run of an application is completely separate from
  586. * other runs. However, with identity set the socket shall re-use any existing 0MQ
  587. * infrastructure configured by the previous run(s). Thus the application may receive
  588. * messages that were sent in the meantime, _message queue_ limits shall be shared with
  589. * previous run(s) and so on.
  590. *
  591. * Identity should be at least one byte and at most 255 bytes long. Identities starting with
  592. * binary zero are reserved for use by 0MQ infrastructure.
  593. *
  594. * @param identity
  595. */
  596. public void setIdentity (byte [] identity) {
  597. setBytesSockopt (IDENTITY, identity);
  598. }
  599. /**
  600. * The 'ZMQ_SUBSCRIBE' option shall establish a new message filter on a 'ZMQ_SUB' socket.
  601. * Newly created 'ZMQ_SUB' sockets shall filter out all incoming messages, therefore you
  602. * should call this option to establish an initial message filter.
  603. *
  604. * An empty 'option_value' of length zero shall subscribe to all incoming messages. A
  605. * non-empty 'option_value' shall subscribe to all messages beginning with the specified
  606. * prefix. Mutiple filters may be attached to a single 'ZMQ_SUB' socket, in which case a
  607. * message shall be accepted if it matches at least one filter.
  608. *
  609. * @param topic
  610. */
  611. public void subscribe (byte [] topic) {
  612. setBytesSockopt (SUBSCRIBE, topic);
  613. }
  614. /**
  615. * The 'ZMQ_UNSUBSCRIBE' option shall remove an existing message filter on a 'ZMQ_SUB'
  616. * socket. The filter specified must match an existing filter previously established with
  617. * the 'ZMQ_SUBSCRIBE' option. If the socket has several instances of the same filter
  618. * attached the 'ZMQ_UNSUBSCRIBE' option shall remove only one instance, leaving the rest in
  619. * place and functional.
  620. *
  621. * @param topic
  622. */
  623. public void unsubscribe (byte [] topic) {
  624. setBytesSockopt (UNSUBSCRIBE, topic);
  625. }
  626. /**
  627. * The 'ZMQ_RATE' option shall set the maximum send or receive data rate for multicast
  628. * transports such as in the man page of zmq_pgm[7] using the specified 'socket'.
  629. *
  630. * @param rate
  631. */
  632. public void setRate (long rate) {
  633. setLongSockopt (RATE, rate);
  634. }
  635. /**
  636. * The 'ZMQ_RECOVERY_IVL' option shall set the recovery interval for multicast transports
  637. * using the specified 'socket'. The recovery interval determines the maximum time in
  638. * seconds that a receiver can be absent from a multicast group before unrecoverable data
  639. * loss will occur.
  640. *
  641. * CAUTION: Excersize care when setting large recovery intervals as the data needed for
  642. * recovery will be held in memory. For example, a 1 minute recovery interval at a data rate
  643. * of 1Gbps requires a 7GB in-memory buffer. {Purpose of this Method}
  644. *
  645. * @param recovery_ivl
  646. */
  647. public void setRecoveryInterval (long recovery_ivl) {
  648. setLongSockopt (RECOVERY_IVL, recovery_ivl);
  649. }
  650. /**
  651. * The 'ZMQ_MCAST_LOOP' option shall control whether data sent via multicast transports
  652. * using the specified 'socket' can also be received by the sending host via loopback. A
  653. * value of zero disables the loopback functionality, while the default value of 1 enables
  654. * the loopback functionality. Leaving multicast loopback enabled when it is not required
  655. * can have a negative impact on performance. Where possible, disable 'ZMQ_MCAST_LOOP' in
  656. * production environments.
  657. *
  658. * @param mcast_loop
  659. */
  660. public void setMulticastLoop (boolean mcast_loop) {
  661. if (ZMQ.version_full() >= ZMQ.make_version(3, 0, 0))
  662. return;
  663. setLongSockopt (MCAST_LOOP, mcast_loop ? 1 : 0);
  664. }
  665. /**
  666. * The 'ZMQ_SNDBUF' option shall set the underlying kernel transmit buffer size for the
  667. * 'socket' to the specified size in bytes. A value of zero means leave the OS default
  668. * unchanged. For details please refer to your operating system documentation for the
  669. * 'SO_SNDBUF' socket option.
  670. *
  671. * @param sndbuf
  672. */
  673. public void setSendBufferSize (long sndbuf) {
  674. setLongSockopt (SNDBUF, sndbuf);
  675. }
  676. /**
  677. * The 'ZMQ_RCVBUF' option shall set the underlying kernel receive buffer size for the
  678. * 'socket' to the specified size in bytes. A value of zero means leave the OS default
  679. * unchanged. For details refer to your operating system documentation for the 'SO_RCVBUF'
  680. * socket option.
  681. *
  682. * @param rcvbuf
  683. */
  684. public void setReceiveBufferSize (long rcvbuf) {
  685. setLongSockopt (RCVBUF, rcvbuf);
  686. }
  687. /**
  688. * Bind to network interface. Start listening for new connections.
  689. *
  690. * @param addr
  691. * the endpoint to bind to.
  692. */
  693. public native void bind (String addr);
  694. /**
  695. * Connect to remote application.
  696. *
  697. * @param addr
  698. * the endpoint to connect to.
  699. */
  700. public native void connect (String addr);
  701. /**
  702. * Send a message.
  703. *
  704. * @param msg
  705. * the message to send, as an array of bytes.
  706. * @param flags
  707. * the flags to apply to the send operation.
  708. * @return true if send was successful, false otherwise.
  709. */
  710. public native boolean send (byte [] msg, int flags);
  711. /**
  712. * Receive a message.
  713. *
  714. * @param flags
  715. * the flags to apply to the receive operation.
  716. * @return the message received, as an array of bytes; null on error.
  717. */
  718. public native byte [] recv (int flags);
  719. /**
  720. * Class constructor.
  721. *
  722. * @param context
  723. * a 0MQ context previously created.
  724. * @param type
  725. * the socket type.
  726. */
  727. protected Socket (Context context, int type) {
  728. // We keep a local handle to context so that
  729. // garbage collection won't be too greedy on it.
  730. this.context = context;
  731. construct (context, type);
  732. }
  733. /** Initialize the JNI interface */
  734. protected native void construct (Context ctx, int type);
  735. /** Free all resources used by JNI interface. */
  736. @Override
  737. protected native void finalize ();
  738. /**
  739. * Get the socket option value, as a long.
  740. *
  741. * @param option
  742. * ID of the option to set.
  743. * @return The socket option value (as a long).
  744. */
  745. protected native long getLongSockopt (int option);
  746. /**
  747. * Get the socket option value, as a byte array.
  748. *
  749. * @param option
  750. * ID of the option to set.
  751. * @return The socket option value (as a byte array).
  752. */
  753. protected native byte [] getBytesSockopt (int option);
  754. /**
  755. * Set the socket option value, given as a long.
  756. *
  757. * @param option
  758. * ID of the option to set.
  759. * @param optval
  760. * value (as a long) to set the option to.
  761. */
  762. protected native void setLongSockopt (int option, long optval);
  763. /**
  764. * Set the socket option value, given as a byte array.
  765. *
  766. * @param option
  767. * ID of the option to set.
  768. * @param optval
  769. * value (as a byte array) to set the option to.
  770. */
  771. protected native void setBytesSockopt (int option, byte [] optval);
  772. /**
  773. * Get the underlying socket handle. This is private because it is only accessed from JNI,
  774. * where Java access controls are ignored.
  775. *
  776. * @return the internal 0MQ socket handle.
  777. */
  778. private long getSocketHandle () {
  779. return this.socketHandle;
  780. }
  781. /** Opaque data used by JNI driver. */
  782. private long socketHandle;
  783. private Context context = null;
  784. // private Constants use the appropriate setter instead.
  785. private static final int HWM = 1;
  786. // public static final int LWM = 2; // No longer supported
  787. private static final int SWAP = 3;
  788. private static final int AFFINITY = 4;
  789. private static final int IDENTITY = 5;
  790. private static final int SUBSCRIBE = 6;
  791. private static final int UNSUBSCRIBE = 7;
  792. private static final int RATE = 8;
  793. private static final int RECOVERY_IVL = 9;
  794. private static final int MCAST_LOOP = 10;
  795. private static final int SNDBUF = 11;
  796. private static final int RCVBUF = 12;
  797. private static final int RCVMORE = 13;
  798. private static final int FD = 14;
  799. private static final int EVENTS = 15;
  800. private static final int TYPE = 16;
  801. private static final int LINGER = 17;
  802. private static final int RECONNECT_IVL = 18;
  803. private static final int BACKLOG = 19;
  804. private static final int RECONNECT_IVL_MAX = 21;
  805. private static final int MAXMSGSIZE = 22;
  806. private static final int SNDHWM = 23;
  807. private static final int RCVHWM = 24;
  808. }
  809. /**
  810. * Inner class: Poller.
  811. */
  812. public static class Poller {
  813. /**
  814. * These values can be ORed to specify what we want to poll for.
  815. */
  816. public static final int POLLIN = 1;
  817. public static final int POLLOUT = 2;
  818. public static final int POLLERR = 4;
  819. /**
  820. * Register a Socket for polling on all events.
  821. *
  822. * @param socket
  823. * the Socket we are registering.
  824. * @return the index identifying this Socket in the poll set.
  825. */
  826. public int register (Socket socket) {
  827. return register (socket, POLLIN | POLLOUT | POLLERR);
  828. }
  829. /**
  830. * Register a Socket for polling on the specified events.
  831. *
  832. * Automatically grow the internal representation if needed.
  833. *
  834. * @param socket
  835. * the Socket we are registering.
  836. * @param events
  837. * a mask composed by XORing POLLIN, POLLOUT and POLLERR.
  838. * @return the index identifying this Socket in the poll set.
  839. */
  840. public int register (Socket socket, int events) {
  841. int pos = -1;
  842. if (! this.freeSlots.isEmpty()) {
  843. // If there are free slots in our array, remove one
  844. // from the free list and use it.
  845. pos = this.freeSlots.remove();
  846. } else {
  847. if (this.next >= this.size) {
  848. // It is necessary to grow the arrays.
  849. // Compute new size for internal arrays.
  850. int nsize = this.size + SIZE_INCREMENT;
  851. // Create new internal arrays.
  852. Socket [] ns = new Socket [nsize];
  853. short [] ne = new short [nsize];
  854. short [] nr = new short [nsize];
  855. // Copy contents of current arrays into new arrays.
  856. for (int i = 0; i < this.next; ++i) {
  857. ns[i] = this.sockets[i];
  858. ne[i] = this.events[i];
  859. nr[i] = this.revents[i];
  860. }
  861. // Swap internal arrays and size to new values.
  862. this.size = nsize;
  863. this.sockets = ns;
  864. this.events = ne;
  865. this.revents = nr;
  866. }
  867. pos = this.next++;
  868. }
  869. this.sockets[pos] = socket;
  870. this.events[pos] = (short) events;
  871. this.used++;
  872. return pos;
  873. }
  874. /**
  875. * Unregister a Socket for polling on the specified events.
  876. *
  877. * @param socket
  878. * the Socket to be unregistered
  879. */
  880. public void unregister (Socket socket) {
  881. for (int i = 0; i < this.next; ++i) {
  882. if (this.sockets[i] == socket) {
  883. this.sockets[i] = null;
  884. this.events[i] = 0;
  885. this.revents[i] = 0;
  886. this.freeSlots.add(i);
  887. --this.used;
  888. // break; ** ciprian@volution.ro **
  889. }
  890. }
  891. }
  892. /**
  893. * Get the socket associated with an index.
  894. *
  895. * @param index
  896. * the desired index.
  897. * @return the Socket associated with that index (or null).
  898. */
  899. public Socket getSocket (int index) {
  900. if (index < 0 || index >= this.next)
  901. return null;
  902. return this.sockets [index];
  903. }
  904. /**
  905. * Get the current poll timeout.
  906. *
  907. * @return the current poll timeout in microseconds.
  908. * @deprecated Timeout handling has been moved to the poll() methods.
  909. */
  910. public long getTimeout () {
  911. return this.timeout;
  912. }
  913. /**
  914. * Set the poll timeout.
  915. *
  916. * @param timeout
  917. * the desired poll timeout in microseconds.
  918. * @deprecated Timeout handling has been moved to the poll() methods.
  919. */
  920. public void setTimeout (long timeout) {
  921. if (timeout < -1)
  922. return;
  923. this.timeout = timeout;
  924. }
  925. /**
  926. * Get the current poll set size.
  927. *
  928. * @return the current poll set size.
  929. */
  930. public int getSize () {
  931. return this.size;
  932. }
  933. /**
  934. * Get the index for the next position in the poll set size.
  935. *
  936. * @return the index for the next position in the poll set size.
  937. */
  938. public int getNext () {
  939. return this.next;
  940. }
  941. /**
  942. * Issue a poll call. If the poller's internal timeout value
  943. * has been set, use that value as timeout; otherwise, block
  944. * indefinitely.
  945. *
  946. * @return how many objects where signalled by poll ().
  947. */
  948. public long poll () {
  949. long tout = -1;
  950. if (this.timeout > -1) {
  951. tout = this.timeout;
  952. }
  953. return poll(tout);
  954. }
  955. /**
  956. * Issue a poll call, using the specified timeout value.
  957. *
  958. * @param tout
  959. * the timeout in microseconds, as per zmq_poll ();
  960. * if -1, it will block indefinitely until an event
  961. * happens; if 0, it will return immediately;
  962. * otherwise, it will wait for at most that many
  963. * microseconds.
  964. *
  965. * @return how many objects where signalled by poll ()
  966. */
  967. public long poll (long tout) {
  968. if (tout < -1) {
  969. return 0;
  970. }
  971. if (this.size <= 0 || this.next <= 0) {
  972. return 0;
  973. }
  974. for (int i = 0; i < this.next; ++i) {
  975. this.revents [i] = 0;
  976. }
  977. return run_poll (this.used, this.sockets, this.events, this.revents, tout);
  978. }
  979. /**
  980. * Check whether the specified element in the poll set was signalled for input.
  981. *
  982. * @param index
  983. *
  984. * @return true if the element was signalled.
  985. */
  986. public boolean pollin (int index) {
  987. return poll_mask (index, POLLIN);
  988. }
  989. /**
  990. * Check whether the specified element in the poll set was signalled for output.
  991. *
  992. * @param index
  993. *
  994. * @return true if the element was signalled.
  995. */
  996. public boolean pollout (int index) {
  997. return poll_mask (index, POLLOUT);
  998. }
  999. /**
  1000. * Check whether the specified element in the poll set was signalled for error.
  1001. *
  1002. * @param index
  1003. *
  1004. * @return true if the element was signalled.
  1005. */
  1006. public boolean pollerr (int index) {
  1007. return poll_mask (index, POLLERR);
  1008. }
  1009. /**
  1010. * Class constructor.
  1011. *
  1012. * @param context
  1013. * a 0MQ context previously created.
  1014. */
  1015. protected Poller (Context context) {
  1016. this(context, SIZE_DEFAULT);
  1017. }
  1018. /**
  1019. * Class constructor.
  1020. *
  1021. * @param context
  1022. * a 0MQ context previously created.
  1023. * @param size
  1024. * the number of Sockets this poller will contain.
  1025. */
  1026. protected Poller (Context context, int size) {
  1027. this.context = context;
  1028. this.size = size;
  1029. this.next = 0;
  1030. this.sockets = new Socket [this.size];
  1031. this.events = new short [this.size];
  1032. this.revents = new short [this.size];
  1033. freeSlots = new LinkedList<Integer>();
  1034. }
  1035. /**
  1036. * Issue a poll call on the specified 0MQ sockets.
  1037. *
  1038. * @param sockets
  1039. * an array of 0MQ Socket objects to poll.
  1040. * @param events
  1041. * an array of short values specifying what to poll for.
  1042. * @param revents
  1043. * an array of short values with the results.
  1044. * @param timeout
  1045. * the maximum timeout in microseconds.
  1046. * @return how many objects where signalled by poll ().
  1047. */
  1048. private native long run_poll (int count, Socket [] sockets, short [] events, short [] revents, long timeout);
  1049. /**
  1050. * Check whether a specific mask was signalled by latest poll call.
  1051. *
  1052. * @param index
  1053. * the index indicating the socket.
  1054. * @param mask
  1055. * a combination of POLLIN, POLLOUT and POLLERR.
  1056. * @return true if specific socket was signalled as specified.
  1057. */
  1058. private boolean poll_mask (int index, int mask) {
  1059. if (mask <= 0 || index < 0 || index >= this.next) {
  1060. return false;
  1061. }
  1062. return (this.revents [index] & mask) > 0;
  1063. }
  1064. private Context context = null;
  1065. private long timeout = -2; // mark as uninitialized
  1066. private int size = 0;
  1067. private int next = 0;
  1068. private int used = 0;
  1069. private Socket [] sockets = null;
  1070. private short [] events = null;
  1071. private short [] revents = null;
  1072. // When socket is removed from polling, store free slots here
  1073. private LinkedList<Integer> freeSlots = null;
  1074. private static final int SIZE_DEFAULT = 32;
  1075. private static final int SIZE_INCREMENT = 16;
  1076. }
  1077. }