• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: socket KPI upcall questions
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: socket KPI upcall questions


  • Subject: Re: socket KPI upcall questions
  • From: Josh Graessley <email@hidden>
  • Date: Mon, 27 Mar 2006 13:01:26 -0800


Answers below...

On Mar 25, 2006, at 4:16 PM, email@hidden wrote:

I'm using the socket KPI in an IOKit driver and I had some questions
about socket upcalls:

1. The documentation in kpi_socket.h for the sock_upcall function says
it can be called concurrently by multiple threads. Is this even true
for a single socket? For example, if I do a socket_connect and it
completes and calls my upcall then while my upcall is running data
becomes available on the socket, will it reenter my upcall to tell me
data is available?

In every instance that I can think of, the upcall is called on the input thread. Since there is currently only one input thread, the upcall will currently never be reentered. I might be forgetting something. Either way, there are no guarantees that there will only be one input thread in the future. The scenario you suggest above may potentially occur in the future. You should not assume that the upcall will not be called concurrently from multiple threads.


What I'm concerned about is that since the upcall doesn't tell you
what event it is calling you for, I'm using a state variable in my
per-socket upcall cookie to know when to move from the "connecting" to
"reading" state. If I can be re-entered while in my upcall, I'll need
to somehow protect my state variable. I've read that you can't block
in an upcall so I'd need to use something like a simple lock (is a
simple safe in an upcall?).

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. For example, if you were to block on a message you send to a user space process through a kernel control socket, if running that process tried to read some data from a network volume (maybe a user home directory), that process would forever stall. Since there is only one input thread and that's sitting waiting for the user process, the network file operation will never complete.


2. If my socket is non-blocking, is it safe to call socket KPI
functions, such as sock_receive from my upcall? I'd like to chain
upcall completions. I see from the source in Darwin that functions
like sock_getpeername take the socket_lock so I wasn't sure if the
socket KPI is safe to call from my upcall.

Calling the socket KPI will work but it's a little messy. Most socket functions do take the socket lock. The upcall would be mostly useless if you couldn't make any socket calls from it, so the socket takes a reference on the socket and drops the lock before calling the upcall function. This means that you can make most socket calls from an upcall function. Again, be careful because in the future, there may be more than one input thread so you may end up with bugs. If you read a header that has a length, then perform another read based on that length from your upcall, it is possible that your upcall may fire again while you were reading the length and you may try to read the length again from another thread, screwing up your stream of data.


Calling sock_accept does not work from the upcall function.

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. You can have one thread service many sockets. This will avoid the problems of reentrancy in your upcall function and the limits on what you can do to a socket from the upcall.

3. If I call socket_connect on a TCP socket, will my upcall be called
if there is a connection failure (e.g. server not listening on that
port) or only on connection success?

Yes. The upcall is called every time a wakeup on the read side occurs. This basically means that anything that would wake a select with that socket watching for reading will cause your upcall to fire. 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.


4. If I call socket_connect on a TCP socket then need to abort it
before my upcall is called for connection completion, is it safe to
just call socket_close?

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.


Hope this helps.

-josh

Attachment: smime.p7s
Description: S/MIME cryptographic signature

 _______________________________________________
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

References: 
 >socket KPI upcall questions (From: email@hidden)

  • Prev by Date: multicast problem on java
  • Next by Date: Re: multicast problem on java
  • Previous by thread: socket KPI upcall questions
  • Next by thread: Re: socket KPI upcall questions
  • Index(es):
    • Date
    • Thread