×

Discussion Board

Results 1 to 11 of 11
  1. #1
    Registered User
    Join Date
    Mar 2003
    Posts
    7

    AsyncStop doesn't stop MMsvSessionObserver

    Hello,
    On my own created thread I'm doing this:
    Code:
    iScheduler = new (ELeave) CActiveScheduler();
    CActiveScheduler::Install(iScheduler);
    iMsvSession = CMsvSession::OpenSyncL(*this);
    iSchedulerWait.Start(); // starts the loop, don't finishes until AsyncStop AND any session event AFTER that
    The loop works fine and the messages are handled in my MMsvSessionObserver::HandleSessionEventL implementation. iSchedulerWait is of type CActiveScheduleWait. This thread handles the message creation/modification in the scheduler's loop. iMsvSession is the active object, which handles the messages to my observer.

    When I'm trying to stop this loop from the main thread by calling:
    Code:
    iSchedulerWait.AsyncStop();
    User::WaitForRequest(iThreadStatus); // hangs until any session event
    AsyncStop doesn't stop the loop, until any session event arrives.

    How to stop this thread correctly?

    Maybe CMsvSession creates some nested scheduler loops?
    If so, how to stop them?

    I've tried calling iMsvSession->Cancel(), iMsvSession->RemoveObserver(*this) or delete iMsvSession before AsyncStop, all of them leave/panic.
    Last edited by Effekt; 2008-12-18 at 12:43.

  2. #2
    Super Contributor
    Join Date
    Jul 2007
    Location
    ShenZhen, China
    Posts
    4,346

    Re: AsyncStop doesn't stop MMsvSessionObserver

    hi Effekt, your code is not very clearly.

    iScheduler is CActiveSchedule, it only be stop in create CActiveSchedule thread's ActiveObject RunL func.
    main thread can't stop the CActiveSchedule.

    and iSchedulerWait seems CActiveScheduleWait. AsyncStop is not sync func, and only stop CActiveScheduleWait loop, not is CActiveSchedule loop.
    ----------------------------
    坚持学习, 坚持编码
    http://www.devdiv.net/
    qxiaoyuan

  3. #3
    Registered User
    Join Date
    Mar 2003
    Posts
    7

    Re: AsyncStop doesn't stop MMsvSessionObserver

    Quote Originally Posted by qxiaoyuan View Post
    hi Effekt, your code is not very clearly.

    iScheduler is CActiveSchedule, it only be stop in create CActiveSchedule thread's ActiveObject RunL func.
    main thread can't stop the CActiveSchedule.

    and iSchedulerWait seems CActiveScheduleWait. AsyncStop is not sync func, and only stop CActiveScheduleWait loop, not is CActiveSchedule loop.
    Yes, that's what I'm trying to do - I'm trying to stop the CActiveScheduleWait loop, which is started by iSchedulerWait.Start(). And it doesn't stop!
    Yes iSchedulerWait is of type CActiveScheduleWait.

    And yes, AsyncStop is not sync func, and because of that I'm calling User::WaitForRequest(iThreadStatus) after it, to wait until it the thread will stop. It stops only when the next event arrives to the HandleSessionEventL, for example, the message is created or moved. How to make it stop waiting for the next event and exit from the CActiveScheduleWait loop immediately?

    CMsvSession is the active object here, you say I should inherit and modify it's RunL() somehow?

    Quote Originally Posted by Class CActiveScheduler documentation
    Although this can be used to start a nested wait loop, this API is deprecated for that specific functionality, and a CActiveSchedulerWait object should be used instead.
    CActiveScheduler::Start/Stop are deprecated in favor of CActiveSchedulerWait::Start/AsyncStop am I right?

    Quote Originally Posted by CActiveSchedulerWait::Start() documentation
    Compared with CActiveScheduler::Start(), this object owns control of the scheduling loop that is started, and that loop can only be stopped by using this objects AsyncStop() function or the CActiveScheduler::Halt() function. Start() only returns when either of thos has occurred.
    It's written here, that CActiveSchedulerWait::Start returns if AsyncStop is called, but in my case it doesn't. Why? How to stop it?
    Last edited by Effekt; 2008-12-18 at 12:39.

  4. #4
    Super Contributor
    Join Date
    Nov 2004
    Location
    Wiltshire, UK
    Posts
    3,644

    Re: AsyncStop doesn't stop MMsvSessionObserver

    There is a reason why we recommend not to use threads and this is it. Many people have problems disinguishing between an object and the execution context (thread) the object exists in.

    Basically you need to create a shared TRequestStatus between the two threads. In the thread doing the messaging stuff you create an active object that waits for its TRequestStatus to be signalled (ie from the other thread). You do this by setting the TRS to KRequestPending and calling SetActive() on the object. When its signalled it calls CActiveScheduler::Stop in its RunL. You need to ensure you can pass the pointer of the TRS in the messaging thread back to the main thread (non messaging thread); normally its passed as a TRequestStatus** in the thread creation parameter.

    To shutdown the messaging thread, in the main thread (ie the one not running the messaging stuff) you create an RThread object that references the handle of the messaging thread (lets call this messagingThread) You then call messagingThread.RequestComplete(TRS_In_Messaging_thread, <Some code, normally KErrNone>). This will then kick the AO in the messaging thread context and shut down the AS and cause the thread to cleanup and stop.

    There are some slightly easier scenarious you can do by using RProperty, but the best scenario is just not to use threads or split the code out into an IPC process where its easier to make sense of the transitions.

    I think there is some stuff in my old blog posts on blogs.forum.nokia.com about how to do this as well....
    Download Symbian OS now! [url]http://developer.symbian.org[/url]

  5. #5
    Registered User
    Join Date
    Mar 2003
    Posts
    7

    Re: AsyncStop doesn't stop MMsvSessionObserver

    Quote Originally Posted by Paul.Todd View Post
    You then call messagingThread.RequestComplete(TRS_In_Messaging_thread, <Some code, normally KErrNone>). This will then kick the AO in the messaging thread context and shut down the AS and cause the thread to cleanup and stop.
    Yes, that might work, someone should try. I missed this function, so thanks, but to late, I've already done the task using dummy CPeriodic in the same thread, which calls ActiveScheduler::Stop, when needed.

    As for ActiveSchedulerWait::AsyncStop, either write in the documentation, that it can't stop AO working in the other thread, or consider it as a bug.

  6. #6
    Super Contributor
    Join Date
    Nov 2004
    Location
    Wiltshire, UK
    Posts
    3,644

    Re: AsyncStop doesn't stop MMsvSessionObserver

    for ActiveSchedulerWait::AsyncStop, either write in the documentation, that it can't stop AO working in the other thread, or consider it as a bug
    Its not bug, its by design, active schedulers exist and are only accessible in the thread context that created them, that's why you can have multiple schedulers per process but one per thread.

    The problem is you are making life difficult for yourself by using threads.
    Download Symbian OS now! [url]http://developer.symbian.org[/url]

  7. #7
    Registered User
    Join Date
    Mar 2003
    Posts
    7

    Re: AsyncStop doesn't stop MMsvSessionObserver

    Quote Originally Posted by Paul.Todd View Post
    Its not bug, its by design, active schedulers exist and are only accessible in the thread context that created them, that's why you can have multiple schedulers per process but one per thread.
    As I said, if it's by design, then point me to the documentation, which states that fact clearly, and say RTFM. Otherwise, it's an undocumented bug. Many APIs has such "schedulers" and don't have the limitation, that it can't be stopped outside the working thread. I don't see any difficulty to make such an API. And Symbian has all the instruments for that, for example, condition variables (RCondVar), semaphores (RSemaphore) and what not. To say more, everything is done already, you told that RequestComplete() stops waiting for the request, so why it's not called directly in AsyncStop? By design... :/

    By the way, what was the idea of creating CActiveSchedulerWait class, if not to bind it to the scheduler, other than the installed active scheduler in order to start/stop it from the different thread? Otherwise, they could just add a couple of static methods to CActiveScheduler, and don't confuse people.

    Quote Originally Posted by Paul.Todd View Post
    The problem is you are making life difficult for yourself by using threads.
    That's your prejudice. If you are using threads properly, they make your life easier. And if the API were fully documented, there would be no problems at all.

    If the function relies on working correctly only in one thread this should be clearly stated in docs. That's my point. Let alone that it's a bad design limitation. There are lots of bad design issues in Symbian, and I think good docs are the adequate solution for now. Rewriting and correcting the documentation, adding simple API usage examples etc., would give Symbian a huge push towards.

  8. #8
    Nokia Developer Moderator
    Join Date
    Feb 2006
    Location
    Oslo, Norway
    Posts
    28,689

    Re: AsyncStop doesn't stop MMsvSessionObserver

    Search for "request semaphore" (including the quotation marks) in the SDK Help, and you will see that this expression appears everywhere combined with the word "thread" (thread's request semaphore, thread request semaphore, thread is waiting on its request semaphore, etc.), and it systematically happens where the documentation is explaining "depths" of asynchronous request handling, IPC, RequestComplete, WaitForXyRequest, etc. So if you are experiencing with threads, and combine them with asynchronous requests, you are expected to read the documentation carefully.
    Especially since in Symbian normally you do not use threads, that is why these nuances are not expressed everywhere, since they are not that important.
    To say more, everything is done already, you told that RequestComplete() stops waiting for the request, so why it's not called directly in AsyncStop? By design... :/
    You are asking that because you do not fully understand the concept of active objects (in fact most probably that is the cause why you think you need threads). The request meant to be completed by the service provider, even if you Cancel a request, it is completed by the service provider. And the scheduler just does not know about the service provider. Completing the request for itself would be possible - obviously you can invoke a method at any time, and RequestComplete is just a methods like anything else), but what would happen with the service provider? It would still work on the request, and complete it - even if the thread would not exist at all by that time. So what you suggest is not the way.[QUOTE]By the way, what was the idea of creating CActiveSchedulerWait class, if not to bind it to the scheduler, other than the installed active scheduler in order to start/stop it from the different thread? Otherwise, they could just add a couple of static methods to CActiveScheduler, and don't confuse people.[QUOTE]Those static methods are there indeed, CActiveScheduler::Start/Stop are both static methods. The reason for introducing CActiveSchedulerWait is to ease tracking of nested scheduler loops - if you CActiveScheduler::Start multiple loops, the next CActiveScheduler::Stop will stop the innermost one, which may happen to still wait for something.
    Nested loops are used for "straightening" asynchronous events:
    Code:
    HackyCode1()
        - StartSomeAsync1(iStatus);
        - SetActive();
        - CActiveScheduler::Start();
        - ... // this line will be executed when CActiveScheduler::Stop is invoked in RunL
    which is fine. However if you have an other AO, and HackyCode2, it may happen that you execute HackyCode1, then HackyCode2 (since a nested loop has been started, your app remains to be responsive, so the user - or anything else - can do something that results in invoking HackyCode2), which is still fine. However if the first request happens to be completed, a CActiveScheduler::Stop gets invoked, and stops the second nested loop. And that can be a problem indeed, HackyCode2 runs forward, while its request has not been completed actually. So CActiveScheduler::Start-s and Stop-s do not form pairs (since there is a single CActiveScheduler instance), but CActiveSchedulerWait::Start-s and AsyncStop-s do, because you have separate instances of them.
    That's your prejudice.
    Paul's prejudices are usually based on experience I would guess :-)
    If you are using threads properly, they make your life easier. And if the API were fully documented, there would be no problems at all.
    You are right about both, however most users do not use threads properly, because in Symbian there is no workaround for the request semaphore, you can not ignore them, because the API-s still rely on them. You can synchronize two threads of yours using critical sections, semaphores, mutexes and some shared memory but whenever you need any kind of system service, TRequestStatus-es appear.

  9. #9
    Registered User
    Join Date
    Mar 2003
    Posts
    7

    Re: AsyncStop doesn't stop MMsvSessionObserver

    Quote Originally Posted by wizard_hu_ View Post
    Especially since in Symbian normally you do not use threads, that is why these nuances are not expressed everywhere, since they are not that important.
    That's a bad excuse. Interestingly, what else "people don't normally use?"

    Quote Originally Posted by wizard_hu_ View Post
    You are asking that because you do not fully understand the concept of active objects (in fact most probably that is the cause why you think you need threads).
    I fully understand the concept. Again, the _concept_. I've read the documentation section about active objects and saw lots of examples. Moreover, I'm using active objects in different threads. I don't have the source code and can't see how it's implemented, and it has nothing to do with the concept. I need threads, because I need concurrent and independent execution. So your statement is wrong and pretty offensive.

    Quote Originally Posted by wizard_hu_ View Post
    The request meant to be completed by the service provider, even if you Cancel a request, it is completed by the service provider. And the scheduler just does not know about the service provider. Completing the request for itself would be possible - obviously you can invoke a method at any time, and RequestComplete is just a methods like anything else), but what would happen with the service provider? It would still work on the request, and complete it - even if the thread would not exist at all by that time.
    If you name the method "CancelRequest", it should cancel the request (through the service provider or anyhow).
    If you name the method "CancelWaitingForRequest", it should stop waiting, but maybe still service provider will complete the request.
    And if your "Cancel" method does nothing, nor canceling the request, nor stopping waiting - that's at least strange.

    CActiveSchedulerWait for nested loops is understandable, thanks for explanation.

    Please tell me, if I have a TRequestStatus from the service provider and call User::WaitForRequest(status) from thread1, this will wait on the thread1 request semaphore; later if i call some kind of service.Cancel() from threadX, it will usually call threadX.RequestComplete() (and so it must be X = 1 to work) or it will use thread1.RequestComplete()? For example, thread1 could be saved somewhere during the first asynchronous request to the service provider:
    Code:
    UserCode1() { // called from thread1
      TRequestStatus status;
      service.Request(&status);
      User::WaitForRequest(status);
    }
    UserCodeX() { // called from threadX
      service.Cancel();
    }
    // service
    Request(TRequestStatus* status) {
      // ... do something ...
      iThread = GetCurrentThread();
    }
    Cancel() {
      // ... do something ...
      iThread.RequestComplete();
    }
    Last edited by Effekt; 2008-12-24 at 18:00.

  10. #10
    Super Contributor
    Join Date
    Jul 2007
    Location
    ShenZhen, China
    Posts
    4,346

    Re: AsyncStop doesn't stop MMsvSessionObserver

    hi Effekt, if x == 1, service.cancel will not chance called until User::WaitForRequest(status); finished.

    if x != 1, when call servie.cancel, it will panic at most place.
    in symbian, most system handle(RFs, RSocketServ) is owned by thread, so another thread use the system handle, os will not match kernel DObject.

    so if you want cancel the request, not User::WaitForRequest, CAtiveSchedule is the best way.

    porting windows / linux code to symbian, need some new design ideology
    ----------------------------
    坚持学习, 坚持编码
    http://www.devdiv.net/
    qxiaoyuan

  11. #11
    Nokia Developer Moderator
    Join Date
    Feb 2006
    Location
    Oslo, Norway
    Posts
    28,689

    Re: AsyncStop doesn't stop MMsvSessionObserver

    TRequestStatus is just a number.
    You alway invoke RequestComplete on a thread (even on an explicit RThread, or an implicit "current thread" when you User::RequestComplete). So RequestComplete sets the value of the given TRequestStatus (which is not related to a thread), and it signals the request semaphore of the affected thread.
    User::WaitForXy methods do the counterpart of this mechanism:
    - they wait for the request semaphore of the current thread to be signalled (if it has been already signalled - value is higher than 0 or something -, they do not wait), then
    -- User::WaitForAnyRequest simply returns (since it has been waitingfor any request)
    -- User::WaitForRequest checks if the status(es) is KRequestPending or not. If KRequestPending, some other request was completed, so the method continues waiting. If not KRequestPending, the method returns.

Similar Threads

  1. JSR-179API provider reset to stop GPS location activity
    By nicholso in forum Mobile Java General
    Replies: 15
    Last Post: 2009-02-06, 11:33
  2. stupid error!
    By bojkar in forum Symbian
    Replies: 1
    Last Post: 2006-12-14, 05:47
  3. How To Stop And Pause Audio File In Midlet
    By mathi77in in forum Mobile Java General
    Replies: 1
    Last Post: 2005-07-18, 15:04
  4. Replies: 0
    Last Post: 2003-04-21, 18:56

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
×