Skip to content

Commit

Permalink
Merge branch 'master' of github.com:JuliaLang/julia
Browse files Browse the repository at this point in the history
  • Loading branch information
JeffBezanson committed May 3, 2013
2 parents f6eaa1b + ecaa02a commit 4707d6e
Show file tree
Hide file tree
Showing 12 changed files with 454 additions and 19 deletions.
11 changes: 11 additions & 0 deletions base/exports.jl
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@

export
# Modules
PCRE,
Expand Down Expand Up @@ -45,6 +46,7 @@ export
Enumerate,
EnvHash,
#FileDes,
FileMonitor,
FileOffset,
Filter,
IO,
Expand All @@ -60,6 +62,7 @@ export
#PipeIn,
#PipeOut,
PipeBuffer,
PollingFileWatcher,
#Port,
#Ports,
#ProcessExited,
Expand Down Expand Up @@ -993,6 +996,9 @@ export
eof,
fd,
fdio,
FDWatcher,
UV_READABLE,
UV_WRITEABLE,
flush,
gethostname,
getipaddr,
Expand All @@ -1011,6 +1017,8 @@ export
nb_available,
open,
open_any_tcp_port,
OS_FD,
OS_SOCKET,
position,
read,
readall,
Expand All @@ -1026,9 +1034,12 @@ export
serialize,
skip,
start_reading,
start_watching,
stop_reading,
start_timer,
stop_timer,
poll_fd,
poll_file,
takebuf_array,
takebuf_string,
truncate,
Expand Down
1 change: 1 addition & 0 deletions base/process.jl
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ function _jl_spawn(cmd::Ptr{Uint8}, argv::Ptr{Ptr{Uint8}}, loop::Ptr{Void}, pp::
c_free(proc)
throw(UVError("spawn"))
end
associate_julia_struct(proc,pp)
return proc
end

Expand Down
2 changes: 1 addition & 1 deletion base/stat.jl
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ immutable Stat
ctime :: Float64
end

Stat(buf::Vector{Uint8}) = Stat(
Stat(buf::Union(Vector{Uint8},Ptr{Uint8})) = Stat(
uint(ccall(:jl_stat_dev, Uint32, (Ptr{Uint8},), buf)),
uint(ccall(:jl_stat_ino, Uint32, (Ptr{Uint8},), buf)),
uint(ccall(:jl_stat_mode, Uint32, (Ptr{Uint8},), buf)),
Expand Down
222 changes: 220 additions & 2 deletions base/stream.jl
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ typealias UVHandle Ptr{Void}
typealias UVStream AsyncStream

const _sizeof_uv_pipe = ccall(:jl_sizeof_uv_pipe_t,Int32,())
const _sizeof_uv_poll = ccall(:jl_sizeof_uv_poll_t,Int32,())
const _sizeof_uv_fs_poll = ccall(:jl_sizeof_uv_fs_poll_t,Csize_t,())
const _sizeof_uv_fs_events = ccall(:jl_sizeof_uv_fs_events_t,Csize_t,())


function eof(s::AsyncStream)
start_reading(s)
Expand Down Expand Up @@ -55,6 +59,140 @@ end

show(io::IO,stream::TTY) = print(io,"TTY(",stream.open?"connected,":"disconnected,",nb_available(stream.buffer)," bytes waiting)")


type FileMonitor
handle::Ptr{Void}
cb::Callback
function FileMonitor(cb, file)
handle = c_malloc(_sizeof_uv_fs_events)
err = ccall(:jl_fs_event_init,Int32, (Ptr{Void}, Ptr{Void}, Ptr{Uint8}, Int32), eventloop(),handle,file,0)
if err == -1
c_free(handle)
throw(UVError("FileMonitor"))
end
this = new(handle,cb)
associate_julia_struct(handle,this)
finalizer(this,close)
this
end
FileMonitor(file) = FileMonitor(false,file)
end

close(t::FileMonitor) = ccall(:jl_close_uv,Void,(Ptr{Void},),t.handle)

const UV_READABLE = 1
const UV_WRITEABLE = 2

#Wrapper for an OS file descriptor (on both Unix and Windows)
immutable OS_FD
fd::Int32
end

#Wrapper for an OS file descriptor (for Windows)
@windows_only immutable OS_SOCKET
handle::Ptr{Void} # On Windows file descriptors are HANDLE's and 64-bit on 64-bit Windows...
end

abstract UVPollingWatcher

type PollingFileWatcher <: UVPollingWatcher
handle::Ptr{Void}
file::ASCIIString
cb::Callback
function PollingFileWatcher(cb, file)
handle = c_malloc(_sizeof_uv_fs_poll)
err = ccall(:uv_fs_poll_init,Int32,(Ptr{Void},Ptr{Void}),eventloop(),handle)
if err == -1
c_free(handle)
throw(UVError("PollingFileWatcher"))
end
this = new(handle, file, cb)
associate_julia_struct(handle,this)
finalizer(this,close)
this
end
PollingFileWatcher(file) = PollingFileWatcher(false,file)
end

type FDWatcher <: UVPollingWatcher
handle::Ptr{Void}
cb::Callback
function FDWatcher(fd::OS_FD)
handle = c_malloc(_sizeof_uv_poll)
err = ccall(:uv_poll_init,Int32,(Ptr{Void},Ptr{Void},Int32),eventloop(),handle,fd.fd)
if err == -1
c_free(handle)
throw(UVError("FDWatcher"))
end
this = new(handle,false)
associate_julia_struct(handle,this)
finalizer(this,close)
this
end
@windows_only function FDWatcher(fd::OS_SOCKET)
handle = c_malloc(_sizeof_uv_poll)
err = ccall(:uv_poll_init_socket,Int32,(Ptr{Void}, Ptr{Void}, Ptr{Void}),
eventloop(), handle, fd.handle)
if err == -1
c_free(handle)
throw(UVError("FDWatcher"))
end
this = new(handle,false)
associate_julia_struct(handle,this)
finalizer(this,close)
this
end
end

close(t::UVPollingWatcher) = ccall(:jl_close_uv,Void,(Ptr{Void},),t.handle)

function start_watching(t::FDWatcher, events)
associate_julia_struct(t.handle, t)
uv_error("start_watching (FD)",
ccall(:jl_poll_start,Int32,(Ptr{Void},Int32),t.handle,events)==-1)
end
start_watching(f::Function, t::FDWatcher, events) = (t.cb = f; start_watching(t,events))

function start_watching(t::PollingFileWatcher, interval)
associate_julia_struct(t.handle, t)
uv_error("start_watching (File)",
ccall(:jl_fs_poll_start,Int32,(Ptr{Void},Ptr{Uint8},Uint32),t.handle,t.file,interval)==-1)
end
start_watching(f::Function, t::PollingFileWatcher, interval) = (t.cb = f;start_watching(t,interval))

function stop_watching(t::FDWatcher)
disassociate_julia_struct(t.handle)
uv_error("stop_watching (FD)",
ccall(:uv_poll_stop,Int32,(Ptr{Void},),t.handle)==-1)
end

function stop_watching(t::PollingFileWatcher)
disassociate_julia_struct(t.handle)
uv_error("stop_watching (File)",
ccall(:uv_fs_poll_stop,Int32,(Ptr{Void},),t.handle)==-1)
end

function _uv_hook_fseventscb(t::FileMonitor,filename::Ptr,events::Int32,status::Int32)
if(isa(t.cb,Function))
# bytestring(convert(Ptr{Uint8},filename)) - seems broken at the moment - got NULL
t.cb(status, events, status)
end
end

function _uv_hook_pollcb(t::FDWatcher,status::Int32,events::Int32)
if(isa(t.cb,Function))
t.cb(status, events)
end
end
function _uv_hook_fspollcb(t::PollingFileWatcher,status::Int32,prev::Ptr,cur::Ptr)
if(isa(t.cb,Function))
t.cb(status, Stat(convert(Ptr{Uint8},prev)), Stat(convert(Ptr{Uint8},cur)))
end
end

_uv_hook_close(uv::FileMonitor) = (uv.handle = 0; nothing)
_uv_hook_close(uv::UVPollingWatcher) = (uv.handle = 0; nothing)

uvtype(::AsyncStream) = UV_STREAM
uvhandle(stream::AsyncStream) = stream.handle

Expand All @@ -66,10 +204,15 @@ handle(s::Ptr{Void}) = s

make_stdout_stream() = _uv_tty2tty(ccall(:jl_stdout_stream, Ptr{Void}, ()))

associate_julia_struct(handle::Ptr{Void},jlobj::ANY) =
ccall(:jl_uv_associate_julia_struct,Void,(Ptr{Void},Any),handle,jlobj)
disassociate_julia_struct(handle::Ptr{Void}) =
ccall(:jl_uv_disassociate_julia_struct,Void,(Ptr{Void},),handle)

function _uv_tty2tty(handle::Ptr{Void})
tty = TTY(handle,true)
tty.line_buffered = false
ccall(:jl_uv_associate_julia_struct,Void,(Ptr{Void},Any),handle,tty)
associate_julia_struct(handle,tty)
tty
end

Expand Down Expand Up @@ -227,6 +370,7 @@ type SingleAsyncWork <: AsyncWork
end
this=new(cb)
this.handle=ccall(:jl_make_async,Ptr{Void},(Ptr{Void},Any),loop,this)
finalizer(this,close)
this
end
end
Expand All @@ -238,6 +382,7 @@ type IdleAsyncWork <: AsyncWork
function IdleAsyncWork(loop::Ptr{Void},cb::Function)
this=new(cb)
this.handle=ccall(:jl_make_idle,Ptr{Void},(Ptr{Void},Any),loop,this)
finalizer(this,close)
this
end
end
Expand All @@ -249,11 +394,80 @@ type TimeoutAsyncWork <: AsyncWork
function TimeoutAsyncWork(loop::Ptr{Void},cb::Function)
this=new(cb)
this.handle=ccall(:jl_make_timer,Ptr{Void},(Ptr{Void},Any),loop,this)
finalizer(this,close)
this
end
end
TimeoutAsyncWork(cb::Function) = TimeoutAsyncWork(eventloop(),cb)

close(t::TimeoutAsyncWork) = ccall(:jl_close_uv,Void,(Ptr{Void},),t.handle)

function poll_fd(s, events::Integer, timeout_ms::Integer)
timeout_at = int64((time() * 1000)) + timeout_ms
wt = WaitTask()

fdw = FDWatcher(s)
start_watching((status, events) -> tasknotify([wt], :poll, status, events), fdw, events)

if (timeout_ms > 0)
timer = TimeoutAsyncWork(status -> tasknotify([wt], :timeout, status))
start_timer(timer, int64(timeout_ms), int64(0))
end

args = yield(wt)

if (timeout_ms > 0) stop_timer(timer) end

stop_watching(fdw)
if isa(args,InterruptException)
rethrow(args)
end

if (args[2] != 0) error ("fd in error") end
if (args[1] == :poll) return args[3] end
if (args[1] == :timeout) return 0 end

error("Error while polling")
end

function poll_file(s, interval::Integer, timeout_ms::Integer)
timeout_at = int64((time() * 1000)) + timeout_ms
wt = WaitTask()

pfw = PollingFileWatcher(s)
start_watching((status,prev,cur) -> tasknotify([wt], :poll, status), pfw, interval)

if (timeout_ms > 0)
timer = TimeoutAsyncWork(status -> tasknotify([wt], :timeout, status))
start_timer(timer, int64(timeout_ms), int64(0))
end

args = yield(wt)

if (timeout_ms > 0) stop_timer(timer) end

stop_watching(pfw)
if isa(args,InterruptException)
rethrow(args)
end

if (args[2] != 0) error ("fd in error") end
if (args[1] == :poll) return 1 end
if (args[1] == :timeout) return 0 end

error("Error while polling")
end

function watch_file(cb, s; poll=false)
if poll
pfw = PollingFileWatcher(cb,s)
start_watching(pfw)
return pfw
else
return FileMonitor(cb,s)
end
end

function _uv_hook_close(uv::AsyncStream)
uv.handle = 0
uv.open = false
Expand All @@ -265,12 +479,16 @@ _uv_hook_close(uv::AsyncWork) = (uv.handle = 0; nothing)
# This serves as a common callback for all async classes
_uv_hook_asynccb(async::AsyncWork, status::Int32) = async.cb(status)


function start_timer(timer::TimeoutAsyncWork,timeout::Int64,repeat::Int64)
associate_julia_struct(timer.handle,timer)
ccall(:uv_update_time,Void,(Ptr{Void},),eventloop())
ccall(:jl_timer_start,Int32,(Ptr{Void},Int64,Int64),timer.handle,timeout,repeat)
end

function stop_timer(timer::TimeoutAsyncWork)
ccall(:jl_timer_stop,Int32,(Ptr{Void},),timer.handle)
disassociate_julia_struct(timer.handle)
ccall(:uv_timer_stop,Int32,(Ptr{Void},),timer.handle)
end

function sleep(sec::Real)
Expand Down
4 changes: 3 additions & 1 deletion base/sysimg.jl
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,9 @@ include("set.jl")
import Core.Undef # used internally by compiler
include("inference.jl")

# For OS sprcific stuff in I/O
include("osutils.jl")

# I/O, strings & printing
include("io.jl")
include("iobuffer.jl")
Expand Down Expand Up @@ -106,7 +109,6 @@ include("serialize.jl")
include("multi.jl")

# system & environment
include("osutils.jl")
include("libc.jl")
include("env.jl")
include("errno.jl")
Expand Down
Loading

0 comments on commit 4707d6e

Please sign in to comment.