Пример #1
0
  /** @inheritDoc */
  public int writeBuf(int fd, byte buffer[], int off, int len) throws IOException {
    int result = 0;
    byte[] buf = buffer;
    if (off != 0) {
      buf = new byte[len];
      System.arraycopy(buffer, off, buf, 0, len);
    }

    if (DEBUG) {
      System.err.println("writeBuf(" + fd + ") before write.");
    }

    result = libc.write(fd, buf, len); // We rely on open0() for setting the socket to non-blocking

    if (result < 0) {
      int err_code = LibCUtil.errno();
      if (err_code == LibC.EWOULDBLOCK) {
        VMThread.getSystemEvents().waitForWriteEvent(fd);
        if (DEBUG) {
          System.err.println("writeBuf(" + fd + ") returned from select. retry.");
        }
        result =
            libc.write(fd, buf, len); // We rely on open0() for setting the socket to non-blocking
      }
      if (DEBUG) {
        System.err.println("writeBuf(" + fd + ") error:");
      }
      LibCUtil.errCheckNeg(result);
    }

    return result;
  }
Пример #2
0
  /** @inheritDoc */
  public int readBuf(int fd, byte b[], int offset, int length) throws IOException {
    byte[] buf = b;
    if (offset != 0) {
      buf = new byte[length];
    }
    int result =
        libc.read(fd, buf, length); // We rely on open0() for setting the socket to non-blocking

    if (result < 0) {
      int err_code = LibCUtil.errno();
      if (err_code == LibC.EWOULDBLOCK) {
        VMThread.getSystemEvents().waitForReadEvent(fd);
        result =
            libc.read(fd, buf, length); // We rely on open0() for setting the socket to non-blocking
      }
      LibCUtil.errCheckNeg(result);
    }

    if (result == 0) {
      // If remote side has shut down the connection gracefully, and all
      // data has been received, recv() will complete immediately with
      // zero bytes received.
      //
      // This is true for Win32/CE and Linux
      result = -1;
    }

    return result;
  }
Пример #3
0
  /**
   * Accept client connections on server socket fd. Blocks until a client connects.
   *
   * @param fd open server socket. See {@link #openServer}.
   * @return a native handle to the network connection.
   * @throws IOException
   */
  public int accept(int fd) throws IOException {
    VMThread.getSystemEvents().waitForReadEvent(fd);

    Socket.sockaddr_in remote_sin = new Socket.sockaddr_in();
    IntByReference address_len = new IntByReference(4);
    int newSocket = sockets.accept(fd, remote_sin, address_len);
    if (newSocket < 0) {
      throw newError(fd, "accept");
    }
    address_len.free();
    set_blocking_flags(newSocket, /*is_blocking*/ false);
    // we could read info about client from remote_sin, but don't need to.

    return newSocket;
  }
Пример #4
0
  /** @inheritDoc */
  public int open(String hostname, int port, int mode) throws IOException {
    // init_sockets(); win32 only
    int fd = -1;

    fd = sockets.socket(Socket.AF_INET, Socket.SOCK_STREAM, 0);
    if (DEBUG) {
      System.err.println("Socket.socket() = " + fd);
    }
    if (fd < 0) {
      throw newError(fd, "socket create");
    }

    set_blocking_flags(fd, /*is_blocking*/ false);

    NetDB.hostent phostent;
    // hostname is always NUL terminated. See socket/Protocol.java for detail.
    phostent = NetDB.INSTANCE.gethostbyname(hostname);
    if (phostent == null) {
      throw newError(fd, "gethostbyname (herrono = " + NetDB.INSTANCE.h_errno() + ")");
    }

    Socket.sockaddr_in destination_sin = new Socket.sockaddr_in();
    destination_sin.sin_family = Socket.AF_INET;
    destination_sin.sin_port = Inet.htons((short) port);
    destination_sin.sin_addr = phostent.h_addr_list[0];

    if (DEBUG) {
      System.err.println("Socket.sockaddr_in: " + destination_sin);
      System.err.println("connect: hostname: " + hostname + " port: " + port + " mode: " + mode);
    }
    if (sockets.connect(fd, destination_sin, destination_sin.size()) < 0) {
      int err_code = LibCUtil.errno();
      if (err_code == LibC.EINPROGRESS || err_code == LibC.EWOULDBLOCK) {
        // When the socket is ready for connect, it becomes *writable*
        // (according to BSD socket spec of select())
        VMThread.getSystemEvents().waitForWriteEvent(fd);
      } else {
        throw newError(fd, "connect");
      }
    }

    return fd;
  }
Пример #5
0
  /**
   * Accept client connections on server socket fd. Blocks until a client connects.
   *
   * @param fd open server socket. See {@link #openServer}.
   * @return a native handle to the network connection.
   * @throws IOException
   */
  public int accept(int fd) throws IOException {
    Socket.sockaddr_in remote_sin = new Socket.sockaddr_in();
    IntByReference address_len = new IntByReference(4);
    int newSocket;

    try {
      if (DEBUG) {
        System.err.println("Socket.accept(" + fd + ", " + remote_sin + ")...");
      }

      newSocket = sockets.accept(fd, remote_sin, address_len);

      if (newSocket < 0) {
        if (DEBUG) {
          System.err.println("Need to block for accept...");
        }

        int err_code = LibCUtil.errno();
        if (err_code == LibC.EAGAIN || err_code == LibC.EWOULDBLOCK) {
          VMThread.getSystemEvents().waitForReadEvent(fd);
          newSocket = sockets.accept(fd, remote_sin, address_len);
          if (newSocket < 0) {
            throw newError(fd, "accept");
          }
        } else {
          // BUG!
          throw newError(fd, "accept");
        }
      }
    } finally {
      address_len.free();
    }

    set_blocking_flags(newSocket, /*is_blocking*/ false);
    // we could read info about client from remote_sin, but don't need to.

    if (DEBUG) {
      System.err.println("    Socket.accept(...) = " + newSocket);
    }
    return newSocket;
  }
Пример #6
0
 /**
  * Wakes up a single thread that is waiting on this object's monitor. If any threads are waiting
  * on this object, one of them is chosen to be awakened. The choice is arbitrary and occurs at the
  * discretion of the implementation. A thread waits on an object's monitor by calling one of the
  * <code>wait</code> methods.
  *
  * <p>The awakened thread will not be able to proceed until the current thread relinquishes the
  * lock on this object. The awakened thread will compete in the usual manner with any other
  * threads that might be actively competing to synchronize on this object; for example, the
  * awakened thread enjoys no reliable privilege or disadvantage in being the next thread to lock
  * this object.
  *
  * <p>This method should only be called by a thread that is the owner of this object's monitor. A
  * thread becomes the owner of the object's monitor in one of three ways:
  *
  * <ul>
  *   <li>By executing a synchronized instance method of that object.
  *   <li>By executing the body of a <code>synchronized</code> statement that synchronizes on the
  *       object.
  *   <li>For objects of type <code>Class,</code> by executing a synchronized static method of that
  *       class.
  * </ul>
  *
  * <p>Only one thread at a time can own an object's monitor.
  *
  * @exception IllegalMonitorStateException if the current thread is not the owner of this object's
  *     monitor.
  * @see java.lang.Object#notifyAll()
  * @see java.lang.Object#wait()
  */
 public final void notify() {
   com.sun.squawk.VMThread.monitorNotify(this, false);
 }
Пример #7
0
 /**
  * Causes current thread to wait until either another thread invokes the {@link
  * java.lang.Object#notify()} method or the {@link java.lang.Object#notifyAll()} method for this
  * object, or a specified amount of time has elapsed.
  *
  * <p>The current thread must own this object's monitor.
  *
  * <p>This method causes the current thread (call it <var>T</var>) to place itself in the wait set
  * for this object and then to relinquish any and all synchronization claims on this object.
  * Thread <var>T</var> becomes disabled for thread scheduling purposes and lies dormant until one
  * of four things happens:
  *
  * <ul>
  *   <li>Some other thread invokes the <tt>notify</tt> method for this object and thread
  *       <var>T</var> happens to be arbitrarily chosen as the thread to be awakened.
  *   <li>Some other thread invokes the <tt>notifyAll</tt> method for this object.
  *   <li>The specified amount of real time has elapsed, more or less. If <tt>timeout</tt> is zero,
  *       however, then real time is not taken into consideration and the thread simply waits until
  *       notified.
  * </ul>
  *
  * The thread <var>T</var> is then removed from the wait set for this object and re-enabled for
  * thread scheduling. It then competes in the usual manner with other threads for the right to
  * synchronize on the object; once it has gained control of the object, all its synchronization
  * claims on the object are restored to the status quo ante - that is, to the situation as of the
  * time that the <tt>wait</tt> method was invoked. Thread <var>T</var> then returns from the
  * invocation of the <tt>wait</tt> method. Thus, on return from the <tt>wait</tt> method, the
  * synchronization state of the object and of thread <tt>T</tt> is exactly as it was when the
  * <tt>wait</tt> method was invoked.
  *
  * <p>Note that the <tt>wait</tt> method, as it places the current thread into the wait set for
  * this object, unlocks only this object; any other objects on which the current thread may be
  * synchronized remain locked while the thread waits.
  *
  * <p>This method should only be called by a thread that is the owner of this object's monitor.
  * See the <code>notify</code> method for a description of the ways in which a thread can become
  * the owner of a monitor.
  *
  * @param timeout the maximum time to wait in milliseconds.
  * @exception IllegalArgumentException if the value of timeout is negative.
  * @exception IllegalMonitorStateException if the current thread is not the owner of the object's
  *     monitor.
  * @exception InterruptedException if another thread has interrupted the current thread. The
  *     <i>interrupted status</i> of the current thread is cleared when this exception is thrown.
  * @see java.lang.Object#notify()
  * @see java.lang.Object#notifyAll()
  */
 public final void wait(long timeout) throws InterruptedException {
   if (timeout < 0) {
     throw new IllegalArgumentException(/*"timeout value is negative"*/ );
   }
   com.sun.squawk.VMThread.monitorWait(this, timeout);
 }
Пример #8
0
 /**
  * Wakes up all threads that are waiting on this object's monitor. A thread waits on an object's
  * monitor by calling one of the <code>wait</code> methods.
  *
  * <p>The awakened threads will not be able to proceed until the current thread relinquishes the
  * lock on this object. The awakened threads will compete in the usual manner with any other
  * threads that might be actively competing to synchronize on this object; for example, the
  * awakened threads enjoy no reliable privilege or disadvantage in being the next thread to lock
  * this object.
  *
  * <p>This method should only be called by a thread that is the owner of this object's monitor.
  * See the <code>notify</code> method for a description of the ways in which a thread can become
  * the owner of a monitor.
  *
  * @exception IllegalMonitorStateException if the current thread is not the owner of this object's
  *     monitor.
  * @see java.lang.Object#notify()
  * @see java.lang.Object#wait()
  */
 public final void notifyAll() {
   com.sun.squawk.VMThread.monitorNotify(this, true);
 }
Пример #9
0
  /** @inheritDoc */
  public int readBuf(int fd, byte b[], int offset, int length) throws IOException {
    byte[] buf = b;
    int result;

    if (offset != 0) {
      if (DEBUG) {
        System.err.println("readBuf() into temp buf");
      }
      buf = new byte[length];
    }

    if (NBIO_WORKS) {
      result =
          libc.read(fd, buf, length); // We rely on open0() for setting the socket to non-blocking
      if (result < 0) {
        int err_code = LibCUtil.errno();
        if (err_code == LibC.EWOULDBLOCK) {
          if (DEBUG) {
            System.err.println("Wait for read in select...");
          }
          VMThread.getSystemEvents().waitForReadEvent(fd);
          result =
              libc.read(
                  fd, buf, length); // We rely on open0() for setting the socket to non-blocking
        }
        LibCUtil.errCheckNeg(result);
      }
    } else {
      // If non-blocking IO doesn't seems to be working, try this hack...

      int bAvail = available(fd); // may throw IOException

      if (bAvail == 0) {
        if (DEBUG) {
          System.err.println("Wait for read in select...");
        }
        VMThread.getSystemEvents().waitForReadEvent(fd);
        bAvail = available(fd);
        if (bAvail == 0) { // woke up because connection is closed
          if (DEBUG) {
            System.err.println("readBuf(" + fd + ") signalling EOF.");
          }
          return -1; // signal EOF
        }
      }
      if (DEBUG) {
        System.err.println("readBuf(" + fd + ") returned from select. retry.");
      }

      int n = Math.min(bAvail, length); // don't read more than is asked for...
      result = libc.read(fd, buf, n); // only read what we know is there...
      LibCUtil.errCheckNeg(result);
    }

    if (result == 0) {
      // If remote side has shut down the connection gracefully, and all
      // data has been received, recv() will complete immediately with
      // zero bytes received.
      //
      // This is true for Win32/CE and Linux
      if (DEBUG) {
        System.err.println("readBuf(" + fd + ") saw remote side shutdown.");
      }
      result = -1;
    }

    if (offset != 0 && result > 0) {
      System.arraycopy(buf, 0, b, offset, result);
    }
    if (DEBUG) {
      System.out.println("readBuf(" + fd + ") = " + result);
    }

    return result;
  }