Re: socket KPI upcall questions
Re: socket KPI upcall questions
- Subject: Re: socket KPI upcall questions
- From: email@hidden
- Date: Mon, 27 Mar 2006 15:13:29 -0800
> What you can't do in an upcall is slightly more subtle than simply
> blocking. You can take a lock. It's okay if you have to block to take
> that lock. What you want to be careful of is blocking on something
> else that might be dependent on the input thread.
Thanks for the clarification. Just to make sure I understand
correctly, it's safe to use my own private IOLock (which uses
lck_mtx_lock) from upcall as long as I'm not holding it to do anything
that might result in a networking, right?
> In general, it is safer to modify shared data structures (with proper
> locking) indicating the socket that has an event waiting, then wakeup
> a thread you created and service the socket from that thread.
I wanted to avoid the thread context switch by chaining socket calls
directly from the upcall rather than signaling another thread. That's
really just a minor performance concern though.
> The kernel has support for calling the upcall on the write side
> wakeup, but that requires a flag be set and there is no way to do
> that through the KPI.
Does this mean if I call sock_send() and it returns EWOULDBLOCK then
my upcall won't be called to tell me when it's okay to continue
sending? If so, could an ioctl be added to set the
upcall-on-write-wakeup flag? Is there a way, even if hacky, to set
that flag for now until there is a way to set it through the KPI?
Otherwise, I think I'll need to implement some kind of polling scheme
to know when it's safe to continue sending.
> I believe this might work. Once socket_close returns, your upcall
> will not be called again. One thing to be very careful of is not
> calling socket_close while you're actually in a call to that socket
> on another thread. In user space, the file descriptor does some
> reference counting, so an operation on the socket in one thread will
> delay a close from occurring on another thread. Since there are no
> file descriptors, that reference counting is missing and the socket
> will close immediately, leading to a panic.
Does the "in another call to that socket" restriction also apply to
the socket KPI itself trying to call my upcall? For example, if I do
socket_connect and then while it is calling my upcall, I call
socket_close from another thread (while the KPI is calling my upcall)?
I skimmed the Darwin source and it appears to do this:
socket_unlock(so, 0);
... call upcall
socket_lock(so, 0);
It seems like it could crash here if I close from another thread
because socket_close may free the socket_t immediately after the above
socket_unlock so when it tries to do the socket_lock above, it'll
reference the freed socket. Now that I think about it, it seems like
that could happen any time the socket is closed since any time data
becomes available, it's going to call my upcall...or am I missing
something?
Is there a way to safely stop all future upcalls for a socket (e.g.
clear the SB_UPCALL flag and/or NULL out of the so_upcall) and/or do a
deferred close of the socket? I'm basically just looking for a safe
way to cancel any operations on a socket and cause it to close (even
if it doesn't actually close until later).
> Hope this helps.
Yes, it was very helpful, thanks!
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Macnetworkprog mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden