PageRenderTime 45ms CodeModel.GetById 3ms app.highlight 33ms RepoModel.GetById 1ms app.codeStats 1ms

/src/org/zeromq/ZMQ.java

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