Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: jruby/jruby
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: f9d652bd5d86
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: eeadc48536a9
Choose a head ref
  • 5 commits
  • 10 files changed
  • 1 contributor

Commits on May 22, 2015

  1. [Truffle] Shim httpdate

    chrisseaton committed May 22, 2015
    Copy the full SHA
    d58998d View commit details
  2. [Truffle] Thread.start

    chrisseaton committed May 22, 2015
    Copy the full SHA
    cae31a2 View commit details
  3. Copy the full SHA
    3efbb8a View commit details
  4. Copy the full SHA
    de8cbc8 View commit details
  5. Copy the full SHA
    eeadc48 View commit details
12 changes: 11 additions & 1 deletion lib/ruby/truffle/shims/time.rb
Original file line number Diff line number Diff line change
@@ -6,4 +6,14 @@
# GNU General Public License version 2
# GNU Lesser General Public License version 2.1

# Empty time file - everything is loaded by default at the moment
class Time

def self.httpdate(string)
Time.now
end

def httpdate
to_s
end

end
12 changes: 12 additions & 0 deletions test/truffle/simple-webrick-server.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
require 'webrick'

root = File.expand_path '~/public_html'
server = WEBrick::HTTPServer.new :Port => 8000, :DocumentRoot => root

trap 'INT' do server.shutdown end

server.mount_proc '/' do |req, res|
res.body = "Hello, world!\n"
end

server.start
Original file line number Diff line number Diff line change
@@ -49,9 +49,14 @@
import org.jruby.RubyEncoding;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.control.RaiseException;
import org.jruby.truffle.runtime.core.RubyArray;
import org.jruby.truffle.runtime.core.RubyBasicObject;
import org.jruby.truffle.runtime.core.RubyClass;
import org.jruby.truffle.runtime.core.RubyString;
import org.jruby.truffle.runtime.sockets.FDSet;
import org.jruby.truffle.runtime.sockets.FDSetFactory;
import org.jruby.truffle.runtime.sockets.FDSetFactoryFactory;
import org.jruby.truffle.runtime.subsystems.ThreadManager;
import org.jruby.util.ByteList;
import org.jruby.util.Dir;
import org.jruby.util.unsafe.UnsafeHolder;
@@ -469,4 +474,83 @@ public RubyString sysread(VirtualFrame frame, RubyBasicObject file, int length)

}

@RubiniusPrimitive(name = "io_select", needsSelf = false)
public static abstract class IOSelectPrimitiveNode extends RubiniusPrimitiveNode {

private static final FDSetFactory fdSetFactory = FDSetFactoryFactory.create();

public IOSelectPrimitiveNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
}

@CompilerDirectives.TruffleBoundary
@Specialization(guards = {"isNil(writables)", "isNil(errorables)"})
public Object select(VirtualFrame frame, RubyArray readables, RubyBasicObject writables, RubyBasicObject errorables, int timeout) {
final Object[] readableObjects = readables.slowToArray();
final int[] readableFds = getFileDescriptors(frame, readables);

final FDSet readableSet = fdSetFactory.create();

for (int fd : readableFds) {
readableSet.set(fd);
}

final int ready = getContext().getThreadManager().runOnce(new ThreadManager.BlockingActionWithoutGlobalLock<Integer>() {
@Override
public Integer block() throws InterruptedException {
return nativeSockets().select(
max(readableFds) + 1,
readableSet.getPointer(),
PointerPrimitiveNodes.NULL_POINTER,
PointerPrimitiveNodes.NULL_POINTER,
PointerPrimitiveNodes.NULL_POINTER);
}
});

return RubyArray.fromObjects(getContext().getCoreLibrary().getArrayClass(),
getSetObjects(readableObjects, readableFds, readableSet),
RubyArray.fromObjects(getContext().getCoreLibrary().getArrayClass()),
RubyArray.fromObjects(getContext().getCoreLibrary().getArrayClass()));
}

private int[] getFileDescriptors(VirtualFrame frame, RubyArray fileDescriptorArray) {
final Object[] objects = fileDescriptorArray.slowToArray();

final int[] fileDescriptors = new int[objects.length];

for (int n = 0; n < objects.length; n++) {
fileDescriptors[n] = (int) rubyWithSelf(frame, objects[n], "@descriptor");
}

return fileDescriptors;
}

private static int max(int[] values) {
assert values.length > 0;

int max = Integer.MIN_VALUE;

for (int n = 0; n < values.length; n++) {
max = Integer.max(max, values[n]);
}

return max;
}

private RubyArray getSetObjects(Object[] objects, int[] fds, FDSet set) {
final Object[] setObjects = new Object[objects.length];
int setFdsCount = 0;

for (int n = 0; n < objects.length; n++) {
if (set.isSet(fds[n])) {
setObjects[setFdsCount] = objects[n];
setFdsCount++;
}
}

return new RubyArray(getContext().getCoreLibrary().getArrayClass(), setObjects, setFdsCount);
}

}

}
Original file line number Diff line number Diff line change
@@ -613,10 +613,38 @@ public GetHostNameNode(RubyContext context, SourceSection sourceSection) {
}

@Specialization
public int listen(RubyBasicObject name, int nameLength) {
public int getHostName(RubyBasicObject name, int nameLength) {
return nativeSockets().gethostname(PointerPrimitiveNodes.getPointer(name), nameLength);
}

}

@CoreMethod(names = "_getpeername", isModuleFunction = true, required = 3)
public abstract static class GetPeerNameNode extends CoreMethodArrayArgumentsNode {

public GetPeerNameNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
}

@Specialization
public int getPeerName(int socket, RubyBasicObject address, RubyBasicObject addressLength) {
return nativeSockets().getpeername(socket, PointerPrimitiveNodes.getPointer(address), PointerPrimitiveNodes.getPointer(addressLength));
}

}

@CoreMethod(names = "_getsockname", isModuleFunction = true, required = 3)
public abstract static class GetSockNameNode extends CoreMethodArrayArgumentsNode {

public GetSockNameNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
}

@Specialization
public int getSockName(int socket, RubyBasicObject address, RubyBasicObject addressLength) {
return nativeSockets().getsockname(socket, PointerPrimitiveNodes.getPointer(address), PointerPrimitiveNodes.getPointer(addressLength));
}

}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
* Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved. This
* code is released under a tri EPL/GPL/LGPL license. You can use it,
* redistribute it and/or modify it under the terms of the:
*
* Eclipse Public License version 1.0
* GNU General Public License version 2
* GNU Lesser General Public License version 2.1
*/
package org.jruby.truffle.runtime.sockets;

import jnr.ffi.Pointer;
import jnr.ffi.provider.MemoryManager;

public class DarwinFDSet implements FDSet {

private final int INT32_SIZE = 4;

private final int DARWIN_FD_SETSIZE = 1024;
private final int DARWIN_NBBY = 8;
private final int DARWIN_NFDBITS = INT32_SIZE * DARWIN_NBBY;
private final int FD_BITS_SIZE = __DARWIN_howmany(DARWIN_FD_SETSIZE, DARWIN_NFDBITS);

private static final MemoryManager memoryManager = jnr.ffi.Runtime.getSystemRuntime().getMemoryManager();

private final Pointer pointer;

public DarwinFDSet() {
pointer = memoryManager.allocateDirect(FD_BITS_SIZE * INT32_SIZE);
}

@Override
public void set(int fd) {
final int index = fd / DARWIN_NFDBITS;
final int offset = index * INT32_SIZE;
pointer.putInt(offset, pointer.getInt(offset) | 1 << (fd % DARWIN_NFDBITS));
}

@Override
public boolean isSet(int fd) {
final int index = fd / DARWIN_NFDBITS;
final int offset = index * INT32_SIZE;
return (pointer.getInt(offset) & (1 << (fd % DARWIN_NFDBITS))) != 0;
}

@Override
public Pointer getPointer() {
return pointer;
}

private static int __DARWIN_howmany(int x, int y) {
return x % y == 0 ? x / y : (x / y) + 1;
}

}
22 changes: 22 additions & 0 deletions truffle/src/main/java/org/jruby/truffle/runtime/sockets/FDSet.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved. This
* code is released under a tri EPL/GPL/LGPL license. You can use it,
* redistribute it and/or modify it under the terms of the:
*
* Eclipse Public License version 1.0
* GNU General Public License version 2
* GNU Lesser General Public License version 2.1
*/
package org.jruby.truffle.runtime.sockets;

import jnr.ffi.Pointer;

public interface FDSet {

void set(int fd);

boolean isSet(int fd);

Pointer getPointer();

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/*
* Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved. This
* code is released under a tri EPL/GPL/LGPL license. You can use it,
* redistribute it and/or modify it under the terms of the:
*
* Eclipse Public License version 1.0
* GNU General Public License version 2
* GNU Lesser General Public License version 2.1
*/
package org.jruby.truffle.runtime.sockets;

public interface FDSetFactory {

FDSet create();

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved. This
* code is released under a tri EPL/GPL/LGPL license. You can use it,
* redistribute it and/or modify it under the terms of the:
*
* Eclipse Public License version 1.0
* GNU General Public License version 2
* GNU Lesser General Public License version 2.1
*/
package org.jruby.truffle.runtime.sockets;

import org.jruby.ext.ffi.Platform;

public abstract class FDSetFactoryFactory {

public static FDSetFactory create() {
switch (Platform.getPlatform().getOS()) {
case DARWIN:
return new FDSetFactory() {

@Override
public FDSet create() {
return new DarwinFDSet();
}

};

default:
throw new UnsupportedOperationException();
}
}

}
Original file line number Diff line number Diff line change
@@ -82,4 +82,28 @@ public interface NativeSockets {

int gethostname(Pointer name, int namelen);

/*
* int
* select(int nfds, fd_set *restrict readfds, fd_set *restrict writefds,
* fd_set *restrict errorfds, struct timeval *restrict timeout);
*/

int select(int nfds, Pointer readfds, Pointer writefds, Pointer errorfds, Pointer timeout);

/*
* int
* getpeername(int socket, struct sockaddr *restrict address,
* socklen_t *restrict address_len);
*/

int getpeername(int socket, Pointer address, Pointer address_len);

/*
* int
* getsockname(int socket, struct sockaddr *restrict address,
* socklen_t *restrict address_len);
*/

int getsockname(int socket, Pointer address, Pointer address_len);

}
4 changes: 4 additions & 0 deletions truffle/src/main/ruby/core/thread.rb
Original file line number Diff line number Diff line change
@@ -20,6 +20,10 @@ def __thread_local_variables
@__thread_local_variables ||= {}
end

def self.start(&block)
Thread.new &block
end

end

class ThreadGroup