-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Reorganization of files to allow distribution of Julia for embedding without uv.h #8880
Conversation
@@ -141,6 +150,13 @@ extern uv_lib_t *jl_winsock_handle; | |||
|
|||
#ifdef __cplusplus | |||
} | |||
|
|||
DLLEXPORT int jl_spawn(char *name, char **argv, uv_loop_t *loop, |
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 should probably not be inside an #ifdef __cplusplus
definitely... I've updated. |
The changes here are not too dramatic and look reasonable to me, thanks for working on this. It would be a bit easier to review if you could rebase away the merge commits, to cut down on the noise. |
I.e. do this while on your local copy of this branch: git fetch
git rebase origin/master |
Ok did that, resolved conflicts, merged fixed, re-merged and pushed. I think I was successful.... |
Almost, but not quite. It seems there are only 4 real commits here. I think the step where things went wrong was the merging - you don't want to merge with this branch, you want to force push over it (prefix the branch name with a + when you do |
Also, those 4 commits should be squashed into 1. |
heh, sorry this is turning into the help the git-newb, Yes there are 4 real commits for this. Everything else is my attempt to equate where upstream is except for the stuff I want to change. The merge was a result of a rebase that had conflicts. I guess there are none now? If I re-rebase will it be more/less successful? I've already rebased though won't it just basically do nothing or replay the conflicts? But, I can do a push -f no problem. To squash all commits into 1 commit, I've read that you can rebase a branch into itself. Something like
To make sure should I fetch upstream and merge master and then rebase the merged master (origin/master) or should I fetch and merge in the branch and then rebase itself onto itself? Or was @StefanKarpinski 's comment about fetching the branch remote to avoid problems with the local branch and the remote? |
I'm not sure, since there appear to be 2 copies of the commits here. Worst case you may have to do the same conflict resolution again, hopefully it wasn't too bad. Since this branch has some nonlinearity going on, I would personally do |
Nah, wasn't bad, just 2 files, but it feels like that is what caused the merge, so I'm worried I'll just end up with another merge. OTOH, I'll just end up with the same thing nothing worse. Do I need to first fetch from upstream, merge into master and then rebase master if I rebase origin/master? Otherwise do I fetch upstream then git rebase -i SHA the most up-to-date commit of the thing I just fetched? Seems the latter is preferable like you said. |
You shouldn't usually need to do merges into the master of your fork, unless it's got some leftover commits that you made some time ago. If you don't care about those any more, you may want to force push over them so your fork is just a delayed copy of upstream's master and you only ever need to do fast-forward pulls or pushes to update your fork's master. What's your favorite workflow for creating a new branch in your fork to work on a new PR? The branches dropdown of your fork in the github web ui? For this PR which already has a branch created, you shouldn't need to do any merging - one of the collaborators will merge it into upstream master once it's done (likely via the merge button in the web ui), but that should be the only merge commit. You also probably don't need to fetch either, unless any upstream changes have introduced new conflicts. Here's the process I just walked through:
result at: https://github.com/tkelman/julia/tree/waT/uvsplit Edit: in your case, the final push would need to be a force push over this branch, so |
Argh. That merge. WTH? What's up with Travis?
On branch master I did
On branch waT/uvsplit I did
There were double the number of commits (2 of the same message) I selected the last ones and squashed the rest and deleted the dups. I re-verified my embed test still works (it's simplistic). But my other project fails now. Does the type String no longer exist? Is it AbstractString only or something? |
Apparently homebrew upgraded gcc to 4.9.2, so we need to ignore osx travis until new binaries are built.
Yeah, #8872 What does |
Oh! #8872. Well that shows that as least I'm picking up the new stuff, and I'm glad I know about it now. But how is the same source to be used for .3.x and .4.x in this case String doesn't exist in .4 and AbstractString doesn't exist in .3.x... Well kind of another topic.
LoL, well that explains it. I thought everyone branched from their own master (git checkout -b from master) and then periodically updated their own master from upstream/master. Heh, I guess not, we
I can rebase again! This time upstream/master, What's likely to happen? |
You can do it that way, but your fork's master has a bunch of accumulated merge commits. As I said earlier, I'd check through the comparison between your fork's master and JuliaLang's master to see whether there's anything there you want to keep. If not, I would checkout
Should end up with a commit that looks identical to waTeim@00e25af but with a parent straight from upstream, instead of one of your merge commits. |
definitions to programs that embed Julia. Femto Lisp include changes required discovered by rebuild. changed comment of ios_buffmode to a deletion Moved decl of jl_spawn inside of extern "C" {}
So is this a problem?
finally. I ended up with
But threw out all but the last thing. The historical stuff was from June, and could not be merged because of submodule differences. So I took a guess and just took the last. The diffs look correct. |
that function (and the rest of |
the loss of |
Maybe a new constructor function?
What would such a constructor take? Or how about something like
|
would also need an |
Because of the field bm
buffmode_t requires uv.h
|
I really like the phrase "git drama". |
Wouldn't it be cleaner to just install our own |
Well does the embedding client need any uv_ stuff? If it's the case that none of jl_uv.c stuff was intended for embedding, then maybe all of the uv_ declarations should be moved to julia_internal.h and only have ios_t available opaquely for stream creation. This is kind of the half-way-not-sure attempt. uv can also be globally installed, and if the embedding client also uses libuv (semi)-directly then I can say from personal experience there can be problems. So if there is a global uv.h and a julia uv.h, which is the correct one? Depending on the include order, it will be the one that's not included. Tricky. So I'd say the cleaner solution is to export only what is absolutely necessary, but of course I'm going to say that. |
It is often useful for C code calling Julia use uv functions. A good example is Conflicts shouldn't be a problem: any program embedding Julia will need to link to Julia's |
I have not had a need to asynchronously call Julia yet, but rather asynchronously call my own thread that synchronously calls Julia, but that sounds interesting. It's not really documented anywhere I've read though. Was that done with jl_spawn or something?
This can be done for at least 2 platforms (OS/X and Linux) from what I've seen so far. I agree that to communicate with Julia using uv, you have to use the uv that Julia was built with, but conversely, to communicate with another framework that uses another uv, you have to use that other framework's uv, and uv is popular enough that you can expect that other people will eventually try to use such a scheme. In such a case interacting with the underlying uv would have to be masked somehow. It would be better to avoid forcing embedding to use Julia's notion of uv unless it's necessary. An API that uses uv internally but exports something Julia only seems cleaner because less baggage. |
I think the long-term goal should be to use the standard libuv, in which case the problem of conflicting version shouldn't arise. |
The use of uv_async_send is documented in the manual. When you are linking to both Julia (and Julia's libuv) and also an external libuv, and you call a libuv function (e.g. uv_async_send), how does it decide which version to use? Are you linking one of them in an RTLD_LOCAL way or something? |
We'll have to bump joyent/libuv#451 back to life to make any progress there. libuv's also about to release 1.0.0 and start following semver rigorously, they might be hesitant about a change that would probably force them to go to 2.0.0 so soon. |
If they don't want to jump to 2.0.0, it would be nice if they would fix their API first, so that we no longer need a fork to make pipes work with process spawn (and other minor issues). That's not really up to us, however. |
I'm not sure that's workable; won't you have to coordinate with at least Joyent and they're using 3 simultaneously - libuv 0.10.x libuv 0.11.x and libuv 1.0.0 <--- as of Sept 24. Not all in 1 deployment!
Heh, now we're getting into #8864, this was revelation that kind of happened by accident when I saw that PPA Ubuntu was working no problem but should not have. But @staticfloat is the one that determined the reason. If the embedding program relies on 2 frameworks A and B use of uv, then on Linux linking with -Bsymbolic-functions will cause A to use uv A, and B to use uv B. OS/X appears to do this by default. The reason we discovered this is Ubuntu uses that flag by default when creating PPA. Apparently, on Windows, this is also possible, but I have no direct experience with it yet. Oh yea, and also
Hmm, RTLD_GLOBAL versus LOCAL? I'm seem to recall LOCAL not working. I shall re-test. But that was to resolve other link problems, not uv stuff. What happens if the embedding program uses uv_async_send directly, I'm not sure, but probably the one that's listed first on the command line in the link step, that correlates at least with my experience. But if it uses uv_async_send indirectly (like above) it's going to end up using the uv_async_send of the framework. So, if Julia were to have a function like jl_async_send, simply a convenient wrapper for uv_async_send, then it would resolve to the one that Julia expects. |
This is starting to sound like what I wound up doing for BLAS - we could objcopy/objconv all of our |
Regarding the embedded troubles that @waTeim faced, we don't need to do anything so exotic as what we needed to do with ILP64 BLAS to make it play nicely. In this case, we aren't doing runtime lookup of libuv functions through something like |
@tkelman Sounds like a good idea anyway, better discuss this patch sooner than later. It's too bad they didn't reply earlier... |
It's been a while, are you looking for me to go ahead and take care of ios_new and ios_free? That would be simple. Is more discussion needed? |
Do we need to do this still? The temp fix actually seems to be ok to me. |
For now. If we can figure out how to get away without installing |
My understanding is that the common case doesn't need it. However, there are a few documented cases where we need to have it (asynchronous) - whether provided by us, or having our modifications accepted upstream. It seems that even if we separate out our internals, we do not have a way to get away without installing uv.h completely. |
Exporting functionality that uses uv underneath is all that's required, so long as sufficient factories of equivalent opaque types that refer back to uv internally are available, uv.h would not be necessary outwardly. But If you mean at minimum uv.h is needed to compile Julia. yes. |
We still could perhaps do this, but this PR is old enough that I'm guessing it probably won't be a helpful starting point anymore. |
Here is a proposal that Fixes #8690 with minimal changes to the interface. It is partially done, but is enough for a source of discussion and/or a short term fix since no embedding can be done currently without uv.h.
Modifications
Most of the embedding interface as been left as is except for.
Limitations
Opaque uv_types
This is ok since all uv-using functions (except 2) take pointers so these type decls can be left incomplete for purposes of providing parameters, however, the embedder can no longer create the uv parameters directly, but must have a factory provided.
missing uv_handle_type
uv_handle_type could also be made opaque, except for 1 problem, it's an enum, not a struct. Unfortunate, but there is only 1 casualty jl_spawn, which is problem, but not an insurmountable one, if the signature changed, or if there were a different function made available for embedding, then the functionality would be preserved.
missing ios_buffmode
Similar to the above for similar reasons, ios_buffmode is not available.