public void terminate() {
        
        tag = 0xdeadbeef;
        
        slot_sync.lock ();
        if (!starting) {

            //  Check whether termination was already underway, but interrupted and now
            //  restarted.
            boolean restarted = terminating;
            terminating = true;
            slot_sync.unlock ();

            //  First attempt to terminate the context.
            if (!restarted) {

                //  First send stop command to sockets so that any blocking calls
                //  can be interrupted. If there are no sockets we can ask reaper
                //  thread to stop.
                slot_sync.lock ();
                try {
                    for (int i = 0; i != sockets.size (); i++)
                        sockets.get(i).stop ();
                    if (sockets.isEmpty ())
                        reaper.stop ();
                } finally {
                    slot_sync.unlock ();
                }
            }

            //  Wait till reaper thread closes all the sockets.
            Command cmd;
            cmd = term_mailbox.recv (-1);
            if (cmd == null)
                throw new IllegalStateException();
            assert (cmd.type() == Command.Type.done);
            slot_sync.lock ();
            assert (sockets.isEmpty ());
        }
        slot_sync.unlock ();

        //  Deallocate the resources.
        destroy();
        
    }