PNGFiles.jl icon indicating copy to clipboard operation
PNGFiles.jl copied to clipboard

Load from a TCPSocket doesn't work

Open joeynelson opened this issue 2 years ago • 2 comments

I have a simple server that just serves up a raw PNG file any client that connects. In Julia I wrote the following function to attempt to load that image.

function ReadTeensyImage(server)
    sock = Sockets.connect(server,555)
    img = load(sock)
    close(sock)
    return img
end

When calling the above function, I get the error below. From what I can tell, the library assumes the IO object has a lock function unless it is a specific type that does not. This approach seems problematic for other packages to add IO types that don't support locking.

Errors encountered while load Stream{DataFormat{:PNG}, TCPSocket, Nothing}(TCPSocket(Base.Libc.WindowsRawSocket(0x0000000000003160) open, 1214 bytes waiting), nothing).
All errors:
===========================================
MethodError: no method matching lock(::PNGFiles.var"#4#5"{Nothing, Bool, Bool, TCPSocket, Ptr{Nothing}, Ptr{Nothing}}, ::TCPSocket)
Closest candidates are:
  lock(::Any, ::Base.GenericCondition) at C:\Users\joey\AppData\Local\Programs\Julia-1.7.2\share\julia\base\condition.jl:78
  lock(::Any, ::Base.AbstractLock) at C:\Users\joey\AppData\Local\Programs\Julia-1.7.2\share\julia\base\lock.jl:187
  lock(::Any, ::Channel) at C:\Users\joey\AppData\Local\Programs\Julia-1.7.2\share\julia\base\channels.jl:425
  ...
===========================================
MethodError: no method matching fd(::TCPSocket)
Closest candidates are:
  fd(::IOStream) at C:\Users\joey\AppData\Local\Programs\Julia-1.7.2\share\julia\base\iostream.jl:55
  fd(::Base.Filesystem.File) at C:\Users\joey\AppData\Local\Programs\Julia-1.7.2\share\julia\base\filesystem.jl:264
===========================================

Fatal error:
ERROR: MethodError: no method matching lock(::PNGFiles.var"#4#5"{Nothing, Bool, Bool, TCPSocket, Ptr{Nothing}, Ptr{Nothing}}, ::TCPSocket)
Closest candidates are:
  lock(::Any, ::Base.GenericCondition) at C:\Users\joey\AppData\Local\Programs\Julia-1.7.2\share\julia\base\condition.jl:78
  lock(::Any, ::Base.AbstractLock) at C:\Users\joey\AppData\Local\Programs\Julia-1.7.2\share\julia\base\lock.jl:187
  lock(::Any, ::Channel) at C:\Users\joey\AppData\Local\Programs\Julia-1.7.2\share\julia\base\channels.jl:425
  ...

joeynelson avatar Mar 10 '22 19:03 joeynelson

What about the following change from:

maybe_lock(f, io::IO) = lock(f, io)
# IOStream doesn't support locking...
maybe_lock(f, io::IOStream) = f()
maybe_lock(f, io::IOBuffer) = f()
maybe_lock(f, io::Base64EncodePipe) = f()
maybe_lock(f, io::IOContext) = maybe_lock(f, io.io)

to:

maybe_lock(f,io::IO) = hasmethod(lock,(typeof(f),typeof(io))) ? lock(f,io) : f()
maybe_lock(f, io::IOContext) = maybe_lock(f, io.io)

joeynelson avatar Mar 11 '22 18:03 joeynelson

Sounds okay to me. Did you happen to verify that this patch works for your case? If so a PR is welcomed.

johnnychen94 avatar Mar 12 '22 10:03 johnnychen94