[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Passive Open using MacTCP



>works fine.  I can make it do (almost) everything I want.  When I do a
>passive open, it hangs until a connection is made.  This limits me to
>supporting one stream at a time.  How can I either be notified (the ASR
>didn't look like it would help), or poll without without repeating passive
>opens and waiting 1 tick?

%tcp-passive-open calls %tcp-control to invoke the MacTCP driver.
%tcp-control does not return until the command is completed. It does this
in the loop:

        (loop
          (when (eql (setq err (#_control :async pb)) 0)
            (let* ((*interrupt-level* 0))
              (while (> (setq err (rref pb tcpioPB.ioResult)) 0))))
          (return))

If you create a version of %tcp-passive-open that calls your own function,
an asynchronous version of %tcp-control (i.e., without the wait loop), then
you can poll tcpioPB.ioResult yourself (= 0 ==> done, < 0 ==> error, > 0
==> pending).

If you are using tcp-streams, then there is some more work required.
initialize-instance of tcp-stream does a (#_DisposPtr pb) after calling
%tcp-passive-open with pb. This won't work with async passive_open; you'll
need to conditionalize it. Perhaps:

      (when (and pb (not async)) ; was pb
        (unless (ccl:%null-ptr-p (rref pb tcpioPB.StreamPtr))
          (%tcp-control pb $TCPRelease T))
        (#_DisposPtr pb)))))

where async is a new keyword arg (default nil) which would also be used to
select your new %tcp-passive-open-async.

As an aside: it looks wrong to me to call (%tcp-control pb $TCPRelease T)
in  initialize-instance even in the sync case. My understanding is that
this should only be called by stream-close after closing the stream (it
balances TCPCreate).
[ TCPCreate [ TCPOpen  [ send/receive ] ... TCPClose ] ... TCPRelease ]
Anybody know why the $TCPRelease is there?

e