×

Discussion Board

Page 1 of 2 12 LastLast
Results 1 to 15 of 22
  1. #1
    Regular Contributor
    Join Date
    Aug 2008
    Posts
    62

    RThread().Id() and RThread.Open() Problem

    Hello,

    I have a little problem concerning RThreads.
    I have two Threads A and B. I want to open the A's handle from B to communicate with it etc. But it dosent' work. Here a simplified snippet.


    // THREAD A
    RThread thrA; // created, up & running

    // In A's thread-context I execute
    TThreadId thrIdA = RThread().Id();
    // printf thrIdA.Id() shows a valid thread Id



    // THREAD B
    RThread thrB; // created, up & running

    // In B's thread-context I execute
    TThreadId thrIdB = RThread().Id();
    // printf thrIdB.Id() shows a valid thread Id

    // An empty TThreadId, later filled by A's thread id.
    TThreadId thrExternal;



    // in THREAD A
    // then, from A's thread-context, I pass A's threadId to thrB
    thrExternal = thrIdA;
    // thrExtrenal.Id() == thrIdA().Id()


    // in THREAD B
    // then, sometime later, I try to communicate with thread A from thread B

    // theExternal.Id() == thrIdA().Id() <- so far so good

    RThread thr;
    int err = thr.Open( thrExternal );
    // err == KErrNone


    // then I wanted to see what's the Id of thr... and the value seems wrong (in any case thr.Id() != thrExternal.Id())

    // so this here won't work as well
    thr.RequestComplete( &iStatusOfThreadA, someCode );
    // iStatusOfThreadA is the iStatus of an ActiveObject in thrA




    Any ideas?

    Thank you in advance.

  2. #2
    Super Contributor
    Join Date
    Jul 2006
    Location
    Oulu, Finland.
    Posts
    1,174

    Re: RThread().Id() and RThread.Open() Problem

    1) what exactly you want to achieve?
    2) I am sure you have no idea how to use 'R' Classes, to use them you generally need to use Open(),Connect() etc.. and Close() or Release() for freeing them.

    3) Try to learn how to create/work with threads in symbian, but again the question would be, Do you really need threads? Is your task real time or of really high priority? Do you have any asynchronous calls? Can you try to achieve the same thing with Active Objects.

    useful links:
    http://wiki.forum.nokia.com/index.ph...0867_-_RThread
    http://wiki.forum.nokia.com/index.ph..._Active_Object
    http://wiki.forum.nokia.com/index.ph...implementation

  3. #3
    Nokia Developer Moderator
    Join Date
    Feb 2006
    Location
    Budapest, Hungary
    Posts
    28,568

    Re: RThread().Id() and RThread.Open() Problem

    Quote Originally Posted by NevenS View Post
    RThread thr;
    int err = thr.Open( thrExternal );
    // err == KErrNone


    // then I wanted to see what's the Id of thr... and the value seems wrong (in any case thr.Id() != thrExternal.Id())
    That is really unlikely. You should log the values.
    // so this here won't work as well
    thr.RequestComplete( &iStatusOfThreadA, someCode );
    // iStatusOfThreadA is the iStatus of an ActiveObject in thrA
    How does it not work exactly? This code snippet would hardly compile in this &iStatusOfThreadA-form. Try pasting simple, but real code.

  4. #4
    Regular Contributor
    Join Date
    Aug 2008
    Posts
    62

    Re: RThread().Id() and RThread.Open() Problem

    Here is a more detailed code-snippet (not a 1to1 copy, but you should get the idea what I am trying to do). The real code I am using compiles and starts (so any syntax errors in here means I typed the code incorrectly into this post, not that the real code has a syntax error..). The GUI works etc.

    What I am trying to do is basically find out, what programming approcahes I can use on symbian. I just want to find out what works and what should work but dosen't..

    I have a GUI application (AppUi being one class of it) with a menu where I can select SomeCommand. I handle this message in AppUi HandleCommand(). There I start myThread, pass the ThreadId of the GUI thread and AppUi::iStatus (AppUi inherits from CActive). Then I do some work in the myThread and want to notify AppUi that the work is finished. But I never get AppUi::RunL() to execute. AppUi is working fine otherwise, as well as MyThread (the thread runs).



    Code:
    class AppUi;
    class MyThread;
    
    
    // AppUi my derivation of the standard framework UI class.
    class AppUi : public CAknAppUi, public CActive {
    
    	// ..standard AppUi class stuff..
    	// ..omitting all the uninteresting details,
    	// the gui is up & running (menu works etc.)
    	
    	AppUi() : CActive(EPriorityStandard) {
    		CActiveScheduler::Add( this );
    	}
    	
    	MyThread* myThread;
    	
    	void RunL() {
    		// do something
    	}
    	
    	void DoCancel() {}
    	
    	// here is a snippet from the correctly running HandleCommandL
    	void HandleCommandL(TInt aCommand)
    	{
    	switch (aCommand)
    		// ..
    		{
    		// getting this command works correctly..
    		case ESomeCommand:
    			{
    			// Create myThread and pass this (UI) thread's Id.
    			myThread = new MyThread();
    			myThread->rqStatus = &iStatus;
    			myThread->rqThreadId = RThread().Id();
    			myThread.thr.Resume();
    			
    			// let's say this thread has debugIdUi = 449
    			TUint64 debugIdUi = RThread().Id().Id();
    			
    			// Since I want myThread to provide an active object service,
    			// I call SetActive() for AppUi
    			SetActive();
    			}
    			break;
    		}
    		//..
    		//..
    	}
    
    };
    
    
    class MyThread {
    	// ..omitting constructor which creates the thread correctly
    
    	RThread thr;
    	TRequestStatus* rqStatus=NULL;
    	TThreadId rqThreadId;	
    	
    	// this is the run-function that runs in thr.
    	virtual void threadRunFunction() {
    		bool shouldRun = true;
    		
    		// let's say this thread has debugIdMyThread = 450
    		TUint64 debugIdMyThread = RThread().Id().Id();
    			
    		while (shouldRun) {
    			// do some task ..
    			
    			// Notify about some task completed
    			if (rqStatus) {
    				RThread extThr;
    				int err = extThr.Open( rqThreadId );
    				// err == 0 (NO ERROR)
    				
    				*rqStatus = KRequestPending;
    				
    				// Contrary to what I would expect, debugExternalIdUi==2151349783 (or some other "random" value)
    				// but it is definetily not debugIdUi==449.
    				// I am not sure if opening a handle to a thread automatically assigns the same ThreadId to the handle.
    				TUint64 debugExternalIdUi = extThr.Id().Id();
    				
    				extThr.RequestComplete( rqStatus, 1234 );
    				
    				extThr.Close();
    			}
    						
    			// this thread still runs after issuing RequestComplete, it should handle other tasks..
    		}
    	}
    }
    Last edited by NevenS; 2008-10-16 at 12:32.

  5. #5
    Registered User
    Join Date
    Dec 2005
    Posts
    1,236

    Re: RThread().Id() and RThread.Open() Problem

    Hi,

    There was a user who was trying to do same thing how he did it for that follow this thread.

    I think you should use RThread::LogOn to get notified the completion of thread.
    Regards,
    Sriky

  6. #6
    Regular Contributor
    Join Date
    Aug 2008
    Posts
    62

    Re: RThread().Id() and RThread.Open() Problem

    thanks for the tip, but I do not want to get notified when a thread ends. I want one thread to call ReqeuestComplete on another thread's TRequestStatus.

    I know it would be best to use active objects, but is it not possible to have one thread notify other thread's TRequestStatus?

  7. #7
    Super Contributor
    Join Date
    Jul 2008
    Location
    Chennai,India
    Posts
    889

    Re: RThread().Id() and RThread.Open() Problem

    You can use the synchronisation primitives...
    You can use a Rsemaphore object...
    One thread can signal it and the other thread could get notified...

    Or the Best method i think is to use RMsgQueue...A global queue in which you can push the messages and the other thread could read it...

    When the thread's Trequeststatus is completed u push the message or signal the semaphore..

  8. #8
    Registered User
    Join Date
    Dec 2005
    Posts
    1,236

    Re: RThread().Id() and RThread.Open() Problem

    Hi,

    I don't quite understand your code whether did you issue the request?
    Regards,
    Sriky

  9. #9
    Regular Contributor
    Join Date
    Aug 2008
    Posts
    62

    Re: RThread().Id() and RThread.Open() Problem

    I know of message queues and the like. But I have a GUI thread in which I cannot explicitly block for a MessageQueue Message. It has to run via Active Objects since the underlying avkon framework uses Active Objects.


    @sriky27
    you mean, whether I issued a request from AppUi to MyThread?
    I think I did it in "case ESomeCommand" in AppUi::HandleCommand.
    Or did I do something wrong there?
    Could it be that I am not issuing request correctly?

  10. #10
    Super Contributor
    Join Date
    Jul 2008
    Location
    Chennai,India
    Posts
    889

    Re: RThread().Id() and RThread.Open() Problem

    Hai Neven..
    If you don't hesitate could you tell us the steps in ur problem generally rather than programmatically...

  11. #11
    Regular Contributor
    Join Date
    Aug 2008
    Posts
    62

    Re: RThread().Id() and RThread.Open() Problem

    @deepchand86
    I have a GUI (derived from stanard avkom GUI). It runs in an own thread (THREAD A, which I don't have to explictly create). Let's name the application user interface class AppUi. It derives from CAknAppUi. And also from CActive, since I want to use ActiveObject-notification to communicate with AppUi (tell it that an event has happend).

    I have another thread (THREAD B) which does something. It has an active scheduler on it's own and uses ActiveObjects on it's own. What I want is THREAD B to notify THREAD A that something has happend.

    Please note that THREAD A is a GUI-Thread. It would be very bad to just wait in HandleCommand() or similar function for messages using RMsgQueue::ReceiveBlocking() (or semaphore etc.). Because that would block the GUI.

    I want THREAD A to get notified when THREAD B does something. My idea was that THREAD A is a CActive and passes it's iStatus to THREAD B. THREAD A calls SetActive() after passing the iStatus. THREAD B opens a handle to THREAD A and calls RequestComplete() thus notifying THREAD A that something has happend.

    Is my approach totally wrong?

  12. #12
    Super Contributor
    Join Date
    Jul 2008
    Location
    Chennai,India
    Posts
    889

    Re: RThread().Id() and RThread.Open() Problem

    K Nevens...
    The Ultimate aim of your problem is to get notified in one thread when an instance occurs in the other thread...

    1.The immediate thing that came to my mind was Callback function..If anything occurs in one thread(Thread B) you send a callback to the other thread's function(Thread A 's func) which will handle that event....
    (But the Thread B wiil be blocking now...But you can spawn a thread to perform this callback function if you need the thread B to be non-blocking and terminate after it finishes..)

    2. Go for RProperty which is publish and subscribe concept..
    You could get the details in the Wiki...

  13. #13
    Regular Contributor
    Join Date
    Aug 2008
    Posts
    62

    Re: RThread().Id() and RThread.Open() Problem

    Thanks for the tip about RProperty. I think that is the soultion, if it would only work on my system.

    I looked up the Wiki RProperty, implemented the CExampleSubscriber but when I try to define a property (RProperty::define) I get a -46 Error code (KErrPermissionDenied).

    I did include the capability WriteDeviceData in .mmp (as suggested by the Symbian SDK Docu). Is this a problem of my certificate?

    And besides RProperty, is there any other way to do what I posted below?

  14. #14
    Nokia Developer Moderator
    Join Date
    Feb 2006
    Location
    Budapest, Hungary
    Posts
    28,568

    Re: RThread().Id() and RThread.Open() Problem

    I think your original idea should still work (the pseudo-code).
    On the implementation part
    - inheriting from CAknAppUi and CActive in the same class is not necessarily a good idea
    - setting the status to KRequestPending should occur in the thread of the AO, 'traditional' place for that is the line before SetActive (normally when you pass a TRequestStatus to an asynchronous service provider, setting to KRequestPending happens in that call)

  15. #15
    Super Contributor
    Join Date
    Jul 2008
    Location
    Chennai,India
    Posts
    889

    Re: RThread().Id() and RThread.Open() Problem

    I think it's a problem with certification..
    You better check the signing procedure and the capabilities supported for symbian...

Posting Permissions

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