Threading problem using AsyncSocket

  • Hello list,
    This is my first attempt at threading with Cocoa, and I am having difficulty
    with my classes that use AsyncSocket.  I am using DetachNewThreadSelector:
    to detach my ‘worker’ thread, and I am instantiating my class that uses
    AsyncSocket from within this thread.  The problem is that the AsyncSocket
    delegates are never called.  This class works just fine from the main
    thread.

    - (IBAction)RunTestButtonPressed:(id)sender
    {
                [NSThread detachNewThreadSelector: @selector(threadFunction:)
    toTarget: self withObject: recipe];
    }

    - (void) threadFunction:(BeverageRecipe*)recipe
    {
    ClassContainingAsyncSocket* foo;
    int i=0;

                while (stuffTodo)
                {
    NSAutoreleasePool* autoReleasePool=[[NSAutoreleasePool alloc]init];

                foo=[[ ClassContainingAsyncSocket alloc]init];

                i=[foo readRegister:0];  //none of the AsyncSocket delegates
    ‘fire!’

                [autoReleasePool release];

    do more stuff….
                }

    }

    Does anyone have any idea what I am missing?  Something fundamentally wrong?
    Thanks in advance for any and all assistance.

    Matt
  • Actually, I think you are correct, however I am still missing something....

    I have added the code:

    NSRunLoop *rLoop [NSRunLoop currentRunLoop];
    RLoop.run;

    And still no delegate methods firing.  Can you or someone please direct me to a resource or an example of setting up a run loop appropriate for a worker thread?

    Again, thanks,
    Matt

    -----Original Message-----
    From: <marcelo.alves...> [mailto:<marcelo.alves...>]On Behalf Of Marcelo Alves
    Sent: Thursday, August 14, 2008 2:55 PM
    To: <matt...>
    Subject: Re: Threading problem using AsyncSocket

    I think you need a runloop in the worker thread.

    2008/8/14 Matthew Youney <matt...>:
    >
    > Hello list,
    > This is my first attempt at threading with Cocoa, and I am having difficulty
    > with my classes that use AsyncSocket.  I am using DetachNewThreadSelector:
    > to detach my 'worker' thread, and I am instantiating my class that uses
    > AsyncSocket from within this thread.  The problem is that the AsyncSocket
    > delegates are never called.  This class works just fine from the main
    > thread.
    >
    > - (IBAction)RunTestButtonPressed:(id)sender
    > {
    > [NSThread detachNewThreadSelector: @selector(threadFunction:)
    > toTarget: self withObject: recipe];
    > }
    >
    >
    > - (void) threadFunction:(BeverageRecipe*)recipe
    > {
    > ClassContainingAsyncSocket* foo;
    > int i=0;
    >
    > while (stuffTodo)
    > {
    > NSAutoreleasePool* autoReleasePool=[[NSAutoreleasePool alloc]init];
    >
    > foo=[[ ClassContainingAsyncSocket alloc]init];
    >
    > i=[foo readRegister:0];  //none of the AsyncSocket delegates
    > 'fire!'
    >
    > [autoReleasePool release];
    >
    >
    > do more stuff....
    > }
    >
    > }
    >
    >
    > Does anyone have any idea what I am missing?  Something fundamentally wrong?
    > Thanks in advance for any and all assistance.
    >
    > Matt
    >
  • Jack,
    Sorry for the confusion, my e-mail program (outlook) capitalized the R.  It
    is indedd rLoop in my code.
    Matt

    -----Original Message-----
    From: Jack Carbaugh [mailto:<intrntmn...>]
    Sent: Thursday, August 14, 2008 4:30 PM
    To: Matthew Youney
    Subject: Re: Threading problem using AsyncSocket

    rLoop and RLoop are two different items i believe.

    since you define rLoop, try

    rLoop.run

    On Aug 14, 2008, at Thu-08 /14 /08-4:20 PM, Matthew Youney wrote:

    > Actually, I think you are correct, however I am still missing
    > something....
    >
    > I have added the code:
    >
    > NSRunLoop *rLoop [NSRunLoop currentRunLoop];
    > RLoop.run;
    >
    > And still no delegate methods firing.  Can you or someone please
    > direct me to a resource or an example of setting up a run loop
    > appropriate for a worker thread?
    >
    > Again, thanks,
    > Matt
    >
    >
    > -----Original Message-----
    > From: <marcelo.alves...>
    > [mailto:<marcelo.alves...>]On Behalf Of Marcelo Alves
    > Sent: Thursday, August 14, 2008 2:55 PM
    > To: <matt...>
    > Subject: Re: Threading problem using AsyncSocket
    >
    > I think you need a runloop in the worker thread.
    >
    >
    > 2008/8/14 Matthew Youney <matt...>:
    >>
    >> Hello list,
    >> This is my first attempt at threading with Cocoa, and I am having
    >> difficulty
    >> with my classes that use AsyncSocket.  I am using
    >> DetachNewThreadSelector:
    >> to detach my 'worker' thread, and I am instantiating my class that
    >> uses
    >> AsyncSocket from within this thread.  The problem is that the
    >> AsyncSocket
    >> delegates are never called.  This class works just fine from the main
    >> thread.
    >>
    >> - (IBAction)RunTestButtonPressed:(id)sender
    >> {
    >> [NSThread detachNewThreadSelector:
    >> @selector(threadFunction:)
    >> toTarget: self withObject: recipe];
    >> }
    >>
    >>
    >> - (void) threadFunction:(BeverageRecipe*)recipe
    >> {
    >> ClassContainingAsyncSocket* foo;
    >> int i=0;
    >>
    >> while (stuffTodo)
    >> {
    >> NSAutoreleasePool* autoReleasePool=[[NSAutoreleasePool alloc]init];
    >>
    >> foo=[[ ClassContainingAsyncSocket alloc]init];
    >>
    >> i=[foo readRegister:0];  //none of the AsyncSocket
    >> delegates
    >> 'fire!'
    >>
    >> [autoReleasePool release];
    >>
    >>
    >> do more stuff....
    >> }
    >>
    >> }
    >>
    >>
    >> Does anyone have any idea what I am missing?  Something
    >> fundamentally wrong?
    >> Thanks in advance for any and all assistance.
    >>
    >> Matt
    >>

  • Jonathan,
    Thank you sooo much for your assistance.  Here's what ended up working for
    me:

    1.    I did update my AsyncSocket class as suggested.  Thanks.
    2.    I determined that my runloop was not functioning as expected using your
    suggestions.  As you said, there is a lot of information here, and although
    I am well-versed now, it was/is new to me (defending my ignorance).  Again,
    thanks!
    3.    I used the ThreadWorker class which has a nice technique for keeping the
    runloop alive while in the worker thread.  This is a very well done class
    that also provides all of the hooks for GUI update, and other niceties.

    I still have one issue:
    I am instantiating my class in the worker thread (as required per AsyncSocet
    docs).  When I dealloc my object (which calls the socket.disconnect method),
    the socket(s) do not disconnect properly, and I end up with a "socket leak".
    If I do not dealloc, the disconnect operation occurs normally, and it
    appears that the "garbage collection" autoreleases the object.  Is this OK?
    Seems kinda sloppy.  Any suggestions?
    Best regards,
    Matt

    Matthew

    1. Are you using the latest AsyncSocket sources?  cocoaasyncsocket - Google
    Code <http://code.google.com/p/cocoaasyncsocket/>

    2. AsyncSocket, though very good, is not perfect. I recently subclassed
    AsyncSocket and encountered a fundamental problem (easily fixed however).
    There could be unrecognised issues with the threading support as threading
    AsyncSocket probably hasn't been attempted that much.

    3. Are the CFSocket callback functions being called in AsyncSocket.m:
    - static void MyCFSocketCallback (CFSocketRef sref, CFSocketCallBackType
    type, CFDataRef address, const void *pData, void *pInfo);
    - static void MyCFReadStreamCallback (CFReadStreamRef stream,
    CFStreamEventType type, void *pInfo);
    - static void MyCFWriteStreamCallback (CFWriteStreamRef stream,
    CFStreamEventType type, void *pInfo);
    Cave man debugging techniques should do the trick there.

    4. Take a good hard look at AsyncSocket.m  -
    (void)doAcceptWithSocket:(CFSocketNativeHandle)newNative and the delegate
    method -[theDelegate onSocket:self wantsRunLoopForNewSocket:newSocket].

    5. Use CFRunLoopContainsSource to check that your socket has been
    successfully added to the correct run loop.

    Good luck!

    Jonathan

    FROM : Matthew Youney
    DATE : Fri Aug 15 00:45:34 2008

    Jonathan,
    The reason I need to thread is not anything to do with AsyncSocket, which is
    an excellent library that does not block.  I have several time consuming
    operations that must occur sequentially.  These sequences need to run
    (start/stop) asynchronous of each other, so I want these to run in separate
    execution threads.

    The "old school" way that I used to manage multiple asynchronous sequences
    like this was to use complex state machines, but I am sure that you will
    agree that separate threads is certainly the way to go.

    I am just having difficulty getting my head around the run loop in the
    worker threads.  I have also tried the ThreadWorker library, that although
    has some awesome features, does not let my AsyncSocket objects run properly.

    And thanks, I appreciate any and all feedback,

    Matt

    -----Original Message-----
    From: cocoa-dev-bounces+matt=youney.<email_removed>
    [ mailto:cocoa-dev-bounces+matt=youney.<email_removed>]On Behalf Of
    <email_removed>
    Sent: Thursday, August 14, 2008 5:04 PM
    To: <email_removed>
    Subject: Re: Threading problem using AsyncSocket (Matthew Youney)

    I don't know about your threading problem but surely the whole point
    of AsyncSocket is the Async bit.
    It is designed to attach itself to the runloop and remove the need for
    blocking sockets etc on threads.

    I use AsyncSocket extensively within the main thread and it can handle
    multiple connection without any problem.

    > Hello list,
    > This is my first attempt at threading with Cocoa, and I am having
    > difficu=
    > lty
    > with my classes that use AsyncSocket.  I am using
    > DetachNewThreadSelector=
    > :
    > to detach my =91worker=92 thread, and I am instantiating my class
    > that us=
    > es
    > AsyncSocket from within this thread.  The problem is that the
    > AsyncSocket
    > delegates are never called.  This class works just fine from the main
    > thread.
    >
    > - (IBAction)RunTestButtonPressed:(id)sender
    > {
    > [NSThread detachNewThreadSelector:
    > @selector(threadFunction:)
    > toTarget: self withObject: recipe];
    > }
    >
    >
    > - (void) threadFunction:(BeverageRecipe*)recipe
    > {
    > ClassContainingAsyncSocket* foo;
    > int i=3D0;
    >
    > while (stuffTodo)
    > {
    > NSAutoreleasePool* autoReleasePool=3D[[NSAutoreleasePool alloc]init];
    >
    > foo=3D[[ ClassContainingAsyncSocket alloc]init];
    >
    > i=3D[foo readRegister:0];  //none of the AsyncSocket
    > delegate=
    > s
    > =91fire!=92
    >
    > [autoReleasePool release];
    >
    >
    > do more stuff=85.
    > }
    >
    > }
    >

    Does anyone have any idea what I am missing?  Something fundamentally
    wro=
    ng?
    Thanks in advance for any and all assistance.

    Matt
  • Jonathan,
    Thank you sooo much for your assistance.  Here's what ended up working for
    me:

    1.    I did update my AsyncSocket class as suggested.  Thanks.
    2.    I determined that my runloop was not functioning as expected using your
    suggestions.  As you said, there is a lot of information here, and although
    I am well-versed now, it was/is new to me (defending my ignorance).  Again,
    thanks!
    3.    I used the ThreadWorker class which has a nice technique for keeping the
    runloop alive while in the worker thread.  This is a very well done class
    that also provides all of the hooks for GUI update, and other niceties.

    I still have one issue:
    I am instantiating my class in the worker thread (as required per AsyncSocet
    docs).  When I dealloc my object (which calls the socket.disconnect method),
    the socket(s) do not disconnect properly, and I end up with a "socket leak".
    If I do not dealloc, the disconnect operation occurs normally, and it
    appears that the "garbage collection" autoreleases the object.  Is this OK?
    Seems kinda sloppy.  Any suggestions?
    Best regards,
    Matt
  • Jonathan,

    You might be interested to know that I just posted some sample code
    demonstrating multithreading with AsyncSocket.  It's a sample HTTP
    server that splits incoming connections across multiple background
    threads.

    Check out the blog post:
    http://deusty.blogspot.com/2008/08/multi-threaded-http-server.html

    -Robbie Hanson
    -Deusty Designs
previous month august 2008 next month
MTWTFSS
        1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
Go to today