-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Make uv_write() a function (was a macro) and do c_free in "finally" clause. Explicit null-termination in jl_safe_printf() to allow for win32's non-posix vsnprintf behaviour. See also #9624. Use jl_safe_printf() in profile thread. Send help message to jl_printf(JL_STDOUT,) was stderr.
- Loading branch information
1 parent
b75971b
commit 2af73dd
Showing
5 changed files
with
16 additions
and
16 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2af73dd
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
BTW, this commit caused a rash of issues with things like
GnuTLS
because it changed the return type ofBase.write()
fromInt
toUInt64
. We've figured it out now however.2af73dd
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd prefer for the return type to be switched back to Int.
2af73dd
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@JeffBezanson If that happens, could you let us know at JuliaWeb so we can synchronize our changes so as not to break things again?
2af73dd
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, Julia-side it is standard to use
Int
for all lengths of arrays and indices into them and things like that, a class of values that the number of bytes written by a write request definitely falls into.2af73dd
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@sbromberger, can you write the relevant code in JuliaWeb defensively so that it will work either way? Otherwise it's hard to sync things up well (not to mention compatibility with older Julia versions).
2af73dd
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@StefanKarpinski we just got finished tagging a new release that works around this change as follows:
const WRITE_RETURN_TYPE = VERSION >= v"0.4-" ? UInt64 : Int64
I guess we could do
const WRITE_RETURN_TYPE = typeof(Base.write(""))
or something to keep it in sync?2af73dd
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@StefanKarpinski @JeffBezanson On second thought, I think this sort of stuff really belongs in Compat. If you change the return type of something in Base, it really should result in a corresponding Compat entry. Thoughts?
2af73dd
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't need to think too hard about how to support both return types, because it's just going to be
Int
.2af73dd
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@JeffBezanson ... but when? Because unless we push some defensive code out there now, that change will break GnuTLS all over again, and even after we fix it, it will be broken for anyone using 0.4 builds from 16 February through the date of the change.
I think this creates an even stronger argument for a Compat entry.
2af73dd
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just wrap the calls to write in
convert(Int,write(...))
– you can even define a customwrite
function that does this. Then it won't matter what integer typewrite
returns.2af73dd
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's in a ccall:
ccall((:gnutls_transport_set_push_function,gnutls),Void,(Ptr{Void},Ptr{Void}),s.handle,cfunction(Base.write,WRITE_RETURN_TYPE,(T,Ptr{Uint8},Csize_t)))
Perhaps a custom write function is the way to go.
2af73dd
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It'll be changed back in a minute. I'm fine with having a Compat entry if you want though.
2af73dd
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@JeffBezanson OK, if you're pushing now, then I can make the change right away. That'll work.
2af73dd
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is an interesting case in how the dynamicism (?) of Julia makes it difficult to ensure correctness. Most of the time, we wouldn't care that the return type is wrong, but since it's in a
cfunction
, we do care. Personally, I think the way to go here forGnuTLS
is to create awrite_wrapper()
that does theconvert()
that Stefan suggests above, and then make acfunction
of that wrapper.If we do change function APIs like this, Compat entries are great, but I'm worried that they will be very difficult to find. Unless we
cfunction
everything, we don't really have a way to ensure our API contracts are correct without just causing ourselves undue pain every time we make a small change to a function that changes its type stability.2af73dd
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we ever get annotated return types on functions this issue will change a lot I think, but until then I don't see an easy way to prevent innocent mistakes like this happening in the future.
2af73dd
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
0.4 is unstable development version, so if you don't bother writing code that works from February 16. until today, you can just check for a faulty version and tell your users to upgrade.
2af73dd
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@staticfloat can you join me in JuliaWeb/GnuTLS.jl#37 for a quick discussion?
2af73dd
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that
cfunction
should just try harder to ensure that return types are correct – I end up writing wrappers that have both convert calls and type assertions on the return value all the time. It seems reasonable forcfunction
to just do that for you. I also think that while it's sometimes useful to get acfunction
for a particular method of an existing C function, it's much more common to define a wrapper in Julia only to get a C function for it, which is currently verbose and repetitive and could be much simpler.2af73dd
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry for the inconvenience @staticfloat, @sbromberger, that is down to poor refactoring discipline on my part. My intention was to avoid changing any user-visible behaviour.
As a Julia newby I'm a little surprised that
cfunction
does not guarantee that the return types is correct.If
cfunction
is told to provide a function pointer to a function returning Int, it should becfunction
's responsibility to do that. If the compiler can't be sure of the return type of a particular method, then it should generate a wrapper that does the conversion.Having written that, then reading the whole conversation above, I realise that I'm pretty much repeating what @StefanKarpinski just said.
Another thing...
Based on this: http://julia.readthedocs.org/en/latest/manual/calling-c-and-fortran-code/#type-correspondences
... it seem like the GnuTls.jl use of
cfunction
is NQR. Should it not be usingClonglong
instead ofInt64
? https://github.com/JuliaWeb/GnuTLS.jl/blob/master/src/GnuTLS.jl#L314The whole
cfunction
andccall
interface seems too fragile.Maybe there is a better way using @Keno's
cxx"
magic. JuliaInterop/Cxx.jl#8 (comment)What if, instead of
cfunction
, you just usecxx"
to define an inline C function. And instead ofccall
you just useicxx"
to call the C function. That way, the C compiler can see the function definition of the callback function, and the call where the function pointer is passed to the C library. And, the C compiler can check the function pointer type.2af73dd
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, um the return type of
write
wasn't checked by the tests in base ?!The not-very-satisfying answer to dynamic languages being unable to provide hard guarantees on type safety is usually "write more tests." Any time an unintended breaking change slips onto master and doesn't get found until it causes problems in packages means we have a hole in our test coverage that needs plugging.
2af73dd
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Most tests look for equality, and we have
0x01 == 1
. Of the 24000+ lines in our test suite, 171 contain calls totypeof
.2af73dd
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps more tests should check for identity since
0x01 !== 1
.2af73dd
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
2af73dd
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Up for grabs issue created: #10251.