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