Skip to content

Enable CF runloop support for linux #101

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

Merged
merged 1 commit into from
Jul 12, 2016

Conversation

dgrove-oss
Copy link
Contributor

Here's a first cut at this. It compiles, but I haven't actually tested it with foundation yet. Implementation mostly based on the code from experimental/foundation, but I decided to more closely mirror the mach code and stash the eventfd in dq->do_ctxt instead of introducing a static variable just for the main queue.

I'm not that happy with the HANDLE (windows) vs. int (linux) aspect of the patch. I partially introduced dispatch_handle_t, but I also should introduce a symbolic constant for 0/NULL and be more careful in the linux-specific code to always use dispatch_handle_t instead of int. Do we want dispatch_handle_t or similar? On as similar note, we could define dispatch_handle_t to be mach_port_t if TARGET_OS_MAC and if we could change the name of _dispatch_get_main_queue_port_4CF to _dispatch_get_main_queue_handle_4CF we could avoid duplicating code.

Also, I used TARGET_OS_MAC in queue.c instead of HAVE_MACH. This is different than other places in queue.c where we guard mach specific code. Is this correct?

#elif defined(__linux__)
int efd = (int)dq->do_ctxt;

if (efd != 0) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

0 is a valid fd, and you will definitely get it if you close STDIN which lots of daemons do, which makes it a bit of an issue. A very gross way to fix that is to store (eventfd + 1) in here

@MadCoder
Copy link
Contributor

MadCoder commented Jul 7, 2016

I don't think we care much about windows, the port is clearly not working, and I would just get rid of that.

Edit: I don't think we care much about trying to maintain that non working windows code and are better off ripping it out so that it gets reported cleanly.

maybe the right thing to do is to have a dispatch_runloop_handle_t rather than dispatch_handle_t which is a bit too generic that abstracts port & fd on linux.

and internally I would have a:

DISPATCH_ALWAYS_INLINE
static inline bool
_dispatch_runloop_handle_is_valid(dispatch_runloop_handle_t handle)
{
#if TARGET_OS_MAC
    return MACH_PORT_VALID(handle);
#elif defined(__linux__)
    return handle >= 0
#else
#error
#endif
}

DISPATCH_ALWAYS_INLINE
static inline dispatch_runloop_handle_t
_dispatch_runloop_queue_get_handle(dispatch_queue_t dq)
{
#if TARGET_OS_MAC
    return ((dispatch_runloop_handle_t)(uintptr_t)dq->dq_ctxt);
#elif defined(__linux__)
    return ((dispatch_runloop_handle_t)(uintptr_t)dq->dq_ctxt) - 1;
#else
#error
#endif
}

DISPATCH_ALWAYS_INLINE
static inline void
_dispatch_runloop_queue_set_handle(dispatch_queue_t dq, dispatch_runloop_handle_t handle)
{
#if TARGET_OS_MAC
    dq->do_ctxt = (void *)(uintptr_t)handle;
#elif defined(__linux__)
    dq->do_ctxt = (void *)(uintptr_t)(handle + 1);
#else
#error
#endif
}

That way the actual mangling of the handle is abstracted away and should allow you to write clean code whether it's a mach port, a file descriptor, a HANDLE, or maybe even something else in the future.

I think you need the +1/-1 trick for fd's because do_ctxt is initialized to 0 where you would want it to be -1, and that is easier to do that mangling above than to try to initialize runloop queues differently.

do you agree?

@@ -23,6 +23,10 @@
#include "protocol.h"
#endif

#if defined(__linux__)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this kind of #include should be in src/internal.h with other dependencies that dispatch needs for most of its source.

@dgrove-oss
Copy link
Contributor Author

Thanks for the quick review!
The suggestion for dispatch_runloop_handle_t and setters/getters makes sense to me. I'll update the patch later tonight.

@parkera
Copy link
Contributor

parkera commented Jul 7, 2016

Not a blocker for this, but we will care about Windows in the long run - both because we actually do use dispatch on windows today, and also because Swift will get ported there soon enough (if it hasn't quite made it already).

@MadCoder
Copy link
Contributor

MadCoder commented Jul 7, 2016

@parkera I completely agree, what I meant is that @dgrove-oss was trying to maintain code that is not wroking at all. the _get_handle() function is actually a prototype only and has no corresponding function in queue.c, and in my experience, it's best to delete half-assed code so that porters aren't misled into thinking this may work.

I wasn't meaning that I don't care about windows, HTH.

EDIT: I updated my poorly worded comment above to clarify this.

@parkera
Copy link
Contributor

parkera commented Jul 8, 2016

Ok, sounds good.

#elif defined(__linux__)
typedef int dispatch_runloop_handle_t;
#else
#error
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#error should have an argument, my example code was just the layout, but an actual error string is good :)

@MadCoder
Copy link
Contributor

MadCoder commented Jul 8, 2016

ok from a cursory glance this looks clean and nice, but I'm too fried to do a proper review now.
I'd also like @das to look at it

@dgrove-oss
Copy link
Contributor Author

Squashed to a single commit.

Confirmed that combined with the changes in swiftlang/swift-corelibs-foundation#434 plus the temporary hack in #100, Foundation links with Dispatch support on Linux and testOperationCount in TestNSOperationQueue passes (however testOperationPriorities hangs). Did not investigate hang since I don't know if the Foundation side of the support is there for that test case yet.

Would be nice to enable some of the dispatch tests that require CoreFoundation. Would it make sense to try to reach into swift-corelibs-foundation from the dispatch build to find CoreFoundation to attempt to build them? Or do you want to defer to testing in the context of swift-corelibs-foundation?

@parkera
Copy link
Contributor

parkera commented Jul 8, 2016

I really want CF to remain a totally private implementation detail of Foundation.

@parkera
Copy link
Contributor

parkera commented Jul 8, 2016

Would it be possible to make these tests use Foundation instead? I guess that would require reimplementing them.

@dgrove-oss dgrove-oss changed the title first cut at updating CF runloop changes for linux Enable CF runloop support for linux Jul 8, 2016
@das
Copy link
Contributor

das commented Jul 8, 2016

i'll take a look asap

@MadCoder
Copy link
Contributor

MadCoder commented Jul 8, 2016

LGTM, @das to rubber stamp too as it affects headers

@MadCoder MadCoder removed their assignment Jul 8, 2016
@@ -166,31 +166,45 @@ void _dispatch_prohibit_transition_to_multithreaded(bool prohibit);
* SPI for CoreFoundation/Foundation ONLY
*/

#define DISPATCH_COCOA_COMPAT (TARGET_OS_MAC || TARGET_OS_WIN32)
#if (TARGET_OS_MAC || TARGET_OS_WIN32)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should remove the WIN32 here, it is just going to #error below anyway

_dispatch_main_queue_callback_4CF(mach_msg_header_t *msg DISPATCH_UNUSED)
#else
_dispatch_main_queue_callback_4CF(void)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this seems like an unnecessary difference if we made the argument void* and just pass in NULL (given that it is not used)

@das
Copy link
Contributor

das commented Jul 12, 2016

one bug and various small style/convention comments but lgtm otherwise, back to you

@das das assigned dgrove-oss and unassigned das Jul 12, 2016
@dgrove-oss
Copy link
Contributor Author

I'd already made changes to private/private.h based on my interpretation of @das comments. I can undo or do differently, just let me know what you'd like. Please be sure to look at the availability macro I put on _dispatch_get_main_queue_handle_4CF. Since this is a new function on MAC_OS, I think it should get these versions, but I'm only guessing.

Once we finalize this, I can update my pull request to foundation to match the final API.

@parkera
Copy link
Contributor

parkera commented Jul 12, 2016

Ok, we can deal with any lockstep changes later probably.

@das
Copy link
Contributor

das commented Jul 12, 2016

Thanks @dgrove-oss that looks exactly like what I had in mind. The new availability annotation should be __OSX_AVAILABLE(10.12) __IOS_AVAILABLE(10.0) __TVOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0) I think
Given the above discussion, it would probably also be useful to add a #define DISPATCH_CF_SPI_VERSION 20160712 define above this section, that CF can use to switch to the new call without revlock.

_dispatch_main_queue_callback_4CF(mach_msg_header_t *_Null_unspecified msg);
#elif TARGET_OS_WIN32
__OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_4_0)
__OSX_AVAILABLE_STARTING(__MAC_10_12,__IPHONE_10_0)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

__OSX_AVAILABLE(10.12) __IOS_AVAILABLE(10.0)
__TVOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0)

@dgrove-oss
Copy link
Contributor Author

availability macros updated and DISPATCH_CF_SPI_VERSION #define added.

@das das merged commit 2c0e5ee into swiftlang:master Jul 12, 2016
@das
Copy link
Contributor

das commented Jul 12, 2016

perfect, thanks

@dgrove-oss dgrove-oss deleted the cf-runloop-hooks branch July 21, 2016 14:42
das added a commit that referenced this pull request Aug 11, 2016
Enable CF runloop support for linux

Signed-off-by: Daniel A. Steffen <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants