All Downloads are FREE. Search and download functionalities are using the official Maven repository.

zmq.Poller Maven / Gradle / Ivy

The newest version!
/*
    Copyright (c) 2009-2011 250bpm s.r.o.
    Copyright (c) 2007-2009 iMatix Corporation
    Copyright (c) 2007-2011 Other contributors as noted in the AUTHORS file

    This file is part of 0MQ.

    0MQ is free software; you can redistribute it and/or modify it under
    the terms of the GNU Lesser General Public License as published by
    the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.

    0MQ is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public License
    along with this program.  If not, see .
*/
package zmq;

import java.io.IOException;
import java.nio.channels.CancelledKeyException;
import java.nio.channels.ClosedChannelException;
import java.nio.channels.SelectableChannel;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

public class Poller extends PollerBase implements Runnable {

    private static class PollSet {
        protected IPollEvents handler;
        protected SelectionKey key;
        protected int ops;
        protected boolean cancelled;
        
        protected PollSet(IPollEvents handler) {
            this.handler = handler;
            key = null;
            cancelled = false;
            ops = 0;
        }
    }
    //  This table stores data for registered descriptors.
    final private Map fd_table;

    //  If true, there's at least one retired event source.
    private boolean retired;

    //  If true, thread is in the process of shutting down.
    volatile private boolean stopping;
    volatile private boolean stopped;
    
    private Thread worker;
    final private Selector selector;
    final private String name;
    
    public Poller() {
        this("poller");
    }
    
    public Poller(String name_) {
        
        name = name_;
        retired = false;
        stopping = false;
        stopped = false;
        
        fd_table = new HashMap();
        try {
            selector = Selector.open();
        } catch (IOException e) {
            throw new ZError.IOException(e);
        }
    }

    public void destroy() {
        
        if (!stopped) {
            try {
                worker.join();
            } catch (InterruptedException e) {
            }
            
            try {
                selector.close();
            } catch (IOException e) {
            }
        }
    }
    public final void add_fd (SelectableChannel fd_, IPollEvents events_)
    {
        fd_table.put(fd_, new PollSet(events_));
        
        adjust_load (1);
        
    }
    

    public final void rm_fd(SelectableChannel handle) {
        
        fd_table.get(handle).cancelled = true;
        retired = true;

        //  Decrease the load metric of the thread.
        adjust_load (-1);
    }
    

    public final void set_pollin (SelectableChannel handle_)
    {
        register(handle_, SelectionKey.OP_READ, false);
    }
    

    public final void reset_pollin (SelectableChannel handle_) {
        register(handle_, SelectionKey.OP_READ, true);
    }
    
    public final void set_pollout (SelectableChannel handle_)
    {
        register(handle_,  SelectionKey.OP_WRITE, false);
    }
    
    public final void reset_pollout (SelectableChannel handle_) {
        register(handle_, SelectionKey.OP_WRITE, true);
    }

    public final void set_pollconnect(SelectableChannel handle_) {
        register(handle_, SelectionKey.OP_CONNECT, false);
    }
    
    public final void set_pollaccept(SelectableChannel handle_) {
        register(handle_, SelectionKey.OP_ACCEPT, false);        
    }

    private final void register (SelectableChannel handle_, int ops, boolean negate)
    {
        PollSet pollset = fd_table.get(handle_);
        
        if (negate) 
            pollset.ops = pollset.ops &~ ops;
        else
            pollset.ops = pollset.ops | ops;
        
        if (pollset.key != null)
            pollset.key.interestOps(pollset.ops);
        else
            retired = true;
    }
    
    public void start() {
        worker = new Thread(this, name);
        worker.start();
    }
    
    public void stop() {
        stopping = true;
        selector.wakeup();
    }
    
    


    @Override
    public void run() {
        
        while (!stopping) {

            //  Execute any due timers.
            long timeout = execute_timers ();
            
            if (retired) {
                
                Iterator> it = fd_table.entrySet().iterator();
                while (it.hasNext()) {
                    Map.Entry entry = it.next();
                    SelectableChannel ch = entry.getKey();
                    PollSet pollset = entry.getValue();
                    if (pollset.key == null) {
                        try {
                            pollset.key = ch.register(selector, pollset.ops, pollset.handler);
                        } catch (ClosedChannelException e) {
                            continue;
                        }
                    } else if (pollset.cancelled) {
                        pollset.key.cancel();
                        it.remove();
                    }
                }
                retired = false;
                
            }

            //  Wait for events.
            int rc;
            try {
                rc = selector.select(timeout);
            } catch (IOException e) {
                throw new ZError.IOException(e);
            }
            
            if (rc == 0) 
                continue;


            Iterator it = selector.selectedKeys().iterator();
            while (it.hasNext()) {
                
                SelectionKey key = it.next();
                IPollEvents evt = (IPollEvents) key.attachment();
                it.remove();

                try {
                    if (key.isReadable() ) {
                        evt.in_event();
                    } else if (key.isAcceptable()) {
                        evt.accept_event();
                    } else if (key.isConnectable()) {
                        evt.connect_event();
                    } 
                    if (key.isWritable()) {
                        evt.out_event();
                    } 
                } catch (CancelledKeyException e) {
                    // channel might have been closed
                }
                
            }

        }
        
        stopped = true;
        
    }

    
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy