PageRenderTime 61ms CodeModel.GetById 3ms app.highlight 48ms RepoModel.GetById 2ms app.codeStats 0ms

/src/org/zeromq/ZMQ.java

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