Skip to content

Commit

Permalink
Merge pull request #12237 from JuliaLang/jn/pollfd_fix2
Browse files Browse the repository at this point in the history
fixes poll_fd
  • Loading branch information
vtjnash committed Jul 27, 2015
2 parents f00af4b + 99b56cd commit 39bd1fc
Show file tree
Hide file tree
Showing 18 changed files with 590 additions and 380 deletions.
4 changes: 2 additions & 2 deletions base/deprecated.jl
Original file line number Diff line number Diff line change
Expand Up @@ -606,15 +606,15 @@ function munmap(viewhandle::Ptr, mmaphandle::Ptr)
status = ccall(:UnmapViewOfFile, stdcall, Cint, (Ptr{Void},), viewhandle)!=0
status |= ccall(:CloseHandle, stdcall, Cint, (Ptr{Void},), mmaphandle)!=0
if !status
error("could not unmap view: $(FormatMessage())")
error("could not unmap view: $(Libc.FormatMessage())")
end
end

function msync(p::Ptr, len::Integer)
depwarn("`msync` is deprecated, use `Mmap.sync!(array)` instead", :msync)
status = ccall(:FlushViewOfFile, stdcall, Cint, (Ptr{Void}, Csize_t), p, len)!=0
if !status
error("could not msync: $(FormatMessage())")
error("could not msync: $(Libc.FormatMessage())")
end
end

Expand Down
27 changes: 4 additions & 23 deletions base/env.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,35 +4,16 @@
_getenv(var::AbstractString) = ccall(:getenv, Ptr{UInt8}, (Cstring,), var)
_hasenv(s::AbstractString) = _getenv(s) != C_NULL
end

@windows_only begin
const ERROR_ENVVAR_NOT_FOUND = UInt32(203)
const FORMAT_MESSAGE_ALLOCATE_BUFFER = UInt32(0x100)
const FORMAT_MESSAGE_FROM_SYSTEM = UInt32(0x1000)
const FORMAT_MESSAGE_IGNORE_INSERTS = UInt32(0x200)
const FORMAT_MESSAGE_MAX_WIDTH_MASK = UInt32(0xFF)
GetLastError() = ccall(:GetLastError,stdcall,UInt32,())
function FormatMessage(e=GetLastError())
lpMsgBuf = Array(Ptr{UInt16})
lpMsgBuf[1] = 0
len = ccall(:FormatMessageW,stdcall,UInt32,(Cint, Ptr{Void}, Cint, Cint, Ptr{Ptr{UInt16}}, Cint, Ptr{Void}),
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_MAX_WIDTH_MASK,
C_NULL, e, 0, lpMsgBuf, 0, C_NULL)
p = lpMsgBuf[1]
len == 0 && return utf8("")
len = len + 1
buf = Array(UInt16, len)
unsafe_copy!(pointer(buf), p, len)
ccall(:LocalFree,stdcall,Ptr{Void},(Ptr{Void},),p)
return utf8(UTF16String(buf))
end

_getenvlen(var::AbstractString) = ccall(:GetEnvironmentVariableW,stdcall,UInt32,(Cwstring,Ptr{UInt8},UInt32),var,C_NULL,0)
_hasenv(s::AbstractString) = _getenvlen(s)!=0 || GetLastError()!=ERROR_ENVVAR_NOT_FOUND
_hasenv(s::AbstractString) = _getenvlen(s)!=0 || Libc.GetLastError()!=ERROR_ENVVAR_NOT_FOUND
function _jl_win_getenv(s::UTF16String,len::UInt32)
val=zeros(UInt16,len)
ret=ccall(:GetEnvironmentVariableW,stdcall,UInt32,(Cwstring,Ptr{UInt16},UInt32),s,val,len)
if (ret == 0 && len != 1) || ret != len-1 || val[end] != 0
error(string("getenv: ", s, ' ', len, "-1 != ", ret, ": ", FormatMessage()))
error(string("getenv: ", s, ' ', len, "-1 != ", ret, ": ", Libc.FormatMessage()))
end
val
end
Expand All @@ -50,7 +31,7 @@ macro accessEnv(var,errorcase)
let var = utf16($(esc(var)))
len=_getenvlen(var)
if len == 0
if GetLastError() != ERROR_ENVVAR_NOT_FOUND
if Libc.GetLastError() != ERROR_ENVVAR_NOT_FOUND
return utf8("")
else
$(esc(errorcase))
Expand Down
4 changes: 2 additions & 2 deletions base/file.jl
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ function tempdir()
temppath = Array(UInt16,32767)
lentemppath = ccall(:GetTempPathW,stdcall,UInt32,(UInt32,Ptr{UInt16}),length(temppath),temppath)
if lentemppath >= length(temppath) || lentemppath == 0
error("GetTempPath failed: $(FormatMessage())")
error("GetTempPath failed: $(Libc.FormatMessage())")
end
resize!(temppath,lentemppath+1)
return utf8(UTF16String(temppath))
Expand All @@ -186,7 +186,7 @@ function tempname(temppath::AbstractString,uunique::UInt32)
uunique = ccall(:GetTempFileNameW,stdcall,UInt32,(Cwstring,Ptr{UInt16},UInt32,Ptr{UInt16}), temppath,utf16("jul"),uunique,tname)
lentname = findfirst(tname,0)-1
if uunique == 0 || lentname <= 0
error("GetTempFileName failed: $(FormatMessage())")
error("GetTempFileName failed: $(Libc.FormatMessage())")
end
resize!(tname,lentname+1)
return utf8(UTF16String(tname))
Expand Down
43 changes: 38 additions & 5 deletions base/libc.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ module Libc

export FILE, TmStruct, strftime, strptime, getpid, gethostname, free, malloc, calloc, realloc,
errno, strerror, flush_cstdio, systemsleep, time
@windows_only export GetLastError, FormatMessage

include("errno.jl")

Expand All @@ -16,14 +17,24 @@ immutable RawFD
RawFD(fd::RawFD) = fd
end

Base.convert(::Type{Int32}, fd::RawFD) = fd.fd
Base.cconvert(::Type{Int32}, fd::RawFD) = fd.fd

dup(x::RawFD) = RawFD(ccall((@windows? :_dup : :dup),Int32,(Int32,),x.fd))
dup(src::RawFD,target::RawFD) = systemerror("dup",-1==
ccall((@windows? :_dup2 : :dup2),Int32,
(Int32,Int32),src.fd,target.fd))

## FILE ##
#Wrapper for an OS file descriptor (for Windows)
@windows_only immutable WindowsRawSocket
handle::Ptr{Void} # On Windows file descriptors are HANDLE's and 64-bit on 64-bit Windows...
end
@windows_only Base.cconvert(::Type{Ptr{Void}}, fd::WindowsRawSocket) = fd.handle

@unix_only _get_osfhandle(fd::RawFD) = fd
@windows_only _get_osfhandle(fd::RawFD) = WindowsRawSocket(ccall(:_get_osfhandle,Ptr{Void},(Cint,),fd.fd))
@windows_only _get_osfhandle(fd::WindowsRawSocket) = fd

## FILE (not auto-finalized) ##

immutable FILE
ptr::Ptr{Void}
Expand All @@ -32,9 +43,9 @@ end
modestr(s::IO) = modestr(isreadable(s), iswritable(s))
modestr(r::Bool, w::Bool) = r ? (w ? "r+" : "r") : (w ? "w" : throw(ArgumentError("neither readable nor writable")))

function FILE(fd, mode)
@unix_only FILEp = ccall(:fdopen, Ptr{Void}, (Cint, Cstring), convert(Cint, fd), mode)
@windows_only FILEp = ccall(:_fdopen, Ptr{Void}, (Cint, Cstring), convert(Cint, fd), mode)
function FILE(fd::RawFD, mode)
@unix_only FILEp = ccall(:fdopen, Ptr{Void}, (Cint, Cstring), fd, mode)
@windows_only FILEp = ccall(:_fdopen, Ptr{Void}, (Cint, Cstring), fd, mode)
systemerror("fdopen", FILEp == C_NULL)
FILE(FILEp)
end
Expand Down Expand Up @@ -155,6 +166,28 @@ errno(e::Integer) = ccall(:jl_set_errno, Void, (Cint,), e)
strerror(e::Integer) = bytestring(ccall(:strerror, Ptr{UInt8}, (Int32,), e))
strerror() = strerror(errno())

@windows_only begin
GetLastError() = ccall(:GetLastError,stdcall,UInt32,())
function FormatMessage(e=GetLastError())
const FORMAT_MESSAGE_ALLOCATE_BUFFER = UInt32(0x100)
const FORMAT_MESSAGE_FROM_SYSTEM = UInt32(0x1000)
const FORMAT_MESSAGE_IGNORE_INSERTS = UInt32(0x200)
const FORMAT_MESSAGE_MAX_WIDTH_MASK = UInt32(0xFF)
lpMsgBuf = Array(Ptr{UInt16})
lpMsgBuf[1] = 0
len = ccall(:FormatMessageW,stdcall,UInt32,(Cint, Ptr{Void}, Cint, Cint, Ptr{Ptr{UInt16}}, Cint, Ptr{Void}),
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_MAX_WIDTH_MASK,
C_NULL, e, 0, lpMsgBuf, 0, C_NULL)
p = lpMsgBuf[1]
len == 0 && return utf8("")
len = len + 1
buf = Array(UInt16, len)
unsafe_copy!(pointer(buf), p, len)
ccall(:LocalFree,stdcall,Ptr{Void},(Ptr{Void},),p)
return utf8(UTF16String(buf))
end
end

## Memory related ##

free(p::Ptr) = ccall(:free, Void, (Ptr{Void},), p)
Expand Down
12 changes: 6 additions & 6 deletions base/mmap.jl
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,8 @@ const FILE_MAP_READ = UInt32(0x04)
const FILE_MAP_EXECUTE = UInt32(0x20)

function gethandle(io::IO)
handle = Base._get_osfhandle(RawFD(fd(io))).handle
systemerror("could not get handle for file to map: $(Base.FormatMessage())", handle == -1)
handle = Libc._get_osfhandle(RawFD(fd(io))).handle
systemerror("could not get handle for file to map: $(Libc.FormatMessage())", handle == -1)
return Int(handle)
end

Expand Down Expand Up @@ -127,18 +127,18 @@ function mmap{T,N}(io::IO,
file_desc, C_NULL, readonly ? PAGE_READONLY : PAGE_READWRITE, szfile >> 32, szfile & typemax(UInt32), name) :
ccall(:OpenFileMappingW, stdcall, Ptr{Void}, (Cint, Cint, Cwstring),
readonly ? FILE_MAP_READ : FILE_MAP_WRITE, true, name)
handle == C_NULL && error("could not create file mapping: $(Base.FormatMessage())")
handle == C_NULL && error("could not create file mapping: $(Libc.FormatMessage())")
ptr = ccall(:MapViewOfFile, stdcall, Ptr{Void}, (Ptr{Void}, Cint, Cint, Cint, Csize_t),
handle, readonly ? FILE_MAP_READ : FILE_MAP_WRITE, offset_page >> 32, offset_page & typemax(UInt32), (offset - offset_page) + len)
ptr == C_NULL && error("could not create mapping view: $(Base.FormatMessage())")
ptr == C_NULL && error("could not create mapping view: $(Libc.FormatMessage())")
end # @windows_only
# convert mmapped region to Julia Array at `ptr + (offset - offset_page)` since file was mapped at offset_page
A = pointer_to_array(convert(Ptr{T}, UInt(ptr) + UInt(offset - offset_page)), dims)
@unix_only finalizer(A, x -> systemerror("munmap", ccall(:munmap,Cint,(Ptr{Void},Int),ptr,mmaplen) != 0))
@windows_only finalizer(A, x -> begin
status = ccall(:UnmapViewOfFile, stdcall, Cint, (Ptr{Void},), ptr)!=0
status |= ccall(:CloseHandle, stdcall, Cint, (Ptr{Void},), handle)!=0
status || error("could not unmap view: $(Base.FormatMessage())")
status || error("could not unmap view: $(Libc.FormatMessage())")
end)
return A
end
Expand Down Expand Up @@ -202,7 +202,7 @@ const MS_SYNC = 4

function sync!{T}(m::Array{T}, flags::Integer=MS_SYNC)
@unix_only systemerror("msync", ccall(:msync, Cint, (Ptr{Void}, Csize_t, Cint), pointer(m), length(m)*sizeof(T), flags) != 0)
@windows_only systemerror("could not FlushViewOfFile: $(Base.FormatMessage())",
@windows_only systemerror("could not FlushViewOfFile: $(Libc.FormatMessage())",
ccall(:FlushViewOfFile, stdcall, Cint, (Ptr{Void}, Csize_t), pointer(m), length(m)) == 0)
end
sync!(B::BitArray, flags::Integer=MS_SYNC) = sync!(B.chunks, flags)
Expand Down
Loading

0 comments on commit 39bd1fc

Please sign in to comment.