You Are Here:

Community: Developer Discussion Boards

Reply « Previous Thread | Next Thread »

#1 Old Trick to prevent Python from closing on red key press. - 2008-06-25, 03:38

Join Date: Jun 2005
Posts: 382
y.a.k
Offline
Regular Contributor
I was playing around and found a way to prevent closing of Python when the red key (hang-up key) is pressed. No external modules are needed.

The trick abuses the fact that PyS60 applications run in Active Objects environment and they spend most of their time in Active Scheduler.

As with standard Python, in PyS60 we can set up a function to be called upon interpreter close. This is simply done by assigning a callable to sys.exitfunc or by using the atexit.register() function.

As it turns out, this function is properly called when the red key is pressed. However, this function has no way to tell Python to abort the close. As soon as this function returns, the interpreter will shut down.

So, we have to make sure it will never return. This is simply done by creating an e32.Ao_lock() object and calling its wait() method each time the system wants to shut Python down.

Let me show you some code:
Code:
import sys, e32
lock = e32.Ao_lock()
sys.exitfunc = lock.wait
That's all, Python will not close now if you press the red key. It will stay in the wait method forever. The wait method internally re-enables scheduling of Active Objects making your menus and UI controls work again.

One issue is that you have to remember to set the sys.exitfunc to None if you will ever want to close Python. Otherwise, it will be impossible to close it. For example, your exit_key_handler in a standalone app could look like this:
Code:
sys.exitfunc = None
appuifw.app.set_exit()
Another issue is that you won't be able to kill Python by pressing C key in task menu. But that may actually be a good thing, depends what kind of app you're writing.

I'm not sure how this will behave in a long run because probably every such quit attempt allocates some memory which is freed only when the application finally closes. But this may be so small that it can be ignored.

All tests done using an N73ME / latest firmware / latest PyS60 (1.4.3). Comments are welcome.

--- Added ---

It happened to me that after coming back to the application, the top pane was gone (no icon, no title). The remedy to this was to force a screen refresh in the exitfunc:
Code:
import sys, e32, appuifw
lock = e32.Ao_lock()
def myexitfunc():
    s = appuifw.app.screen
    appuifw.app.screen = 'large'
    appuifw.app.screen = s
    lock.wait()
sys.exitfunc = myexitfunc
Last edited by y.a.k : 2008-06-25 at 04:16.
Reply With Quote

#2 Old Re: Trick to prevent Python from closing on red key press. - 2008-06-25, 07:17

Join Date: Oct 2007
Posts: 2,845
Location: Deva, Romania
bogdan.galiceanu's Avatar
bogdan.galiceanu
Online
Forum Nokia Champion
That's really great . I for one didn't know we could to that. Congrats on the discovery .

I tested it on N95, v21 firmware and Python 1.4.3 and it worked just like it did for you. And to kill Python I used Handy Taskman to kill its process.

Again, nice trick
Reply With Quote

#3 Old Re: Trick to prevent Python from closing on red key press. - 2008-06-25, 07:30

Join Date: Sep 2005
Posts: 314
Location: Finland, Helsinki
aaaaapo
Offline
Regular Contributor
Quote:
Originally Posted by y.a.k View Post
One issue is that you have to remember to set the sys.exitfunc to None if you will ever want to close Python. Otherwise, it will be impossible to close it.
Could it be possible to count redkey presses and after Nth press close python application?

--
Aapo
Reply With Quote

#4 Old Re: Trick to prevent Python from closing on red key press. - 2008-06-25, 07:40

Join Date: Oct 2007
Posts: 2,845
Location: Deva, Romania
bogdan.galiceanu's Avatar
bogdan.galiceanu
Online
Forum Nokia Champion
Quote:
Originally Posted by aaaaapo View Post
Could it be possible to count redkey presses and after Nth press close python application?

--
Aapo
You mean something like this?

Code:
import appuifw, e32, sys
from keycapture import *
from key_codes import *


lock = e32.Ao_lock()
def myexitfunc():
	s = appuifw.app.screen
	appuifw.app.screen = 'large'
	appuifw.app.screen = s
	lock.wait()
sys.exitfunc = myexitfunc

def quit():
	capturer.stop()
	lock.signal()

c=0

def cb_capture(key):
	global c
	if(key==EKeyNo):c+=1
	if(c==4):quit()   #When the key has been pressed a cetain number of times, exit

capturer=KeyCapturer(cb_capture)
capturer.keys=(all_keys)

capturer.start()
Reply With Quote

#5 Old Re: Trick to prevent Python from closing on red key press. - 2008-06-25, 08:29

Join Date: May 2007
Posts: 2,739
Location: 21.46 N 72.11 E
croozeus's Avatar
croozeus
Offline
Forum Nokia Champion
Hi,

Good discovery y.a.k,

Till now the only solution to prevent the red key terminate python was Envy Module by Cyke64,

Happy Pythoning,

Best Regards,
Croozeus
Reply With Quote

#6 Old Re: Trick to prevent Python from closing on red key press. - 2008-06-25, 11:59

Join Date: Jun 2005
Posts: 382
y.a.k
Offline
Regular Contributor
Thanks guys!

Bogdan, counting could also be done without the KeyCapturer (which requires SwEvent capability). Just increase a global count variable in exitfunc() and if it reaches certain amount, don't call the lock.wait() but simply return, Python will close.
Reply With Quote

#7 Old Re: Trick to prevent Python from closing on red key press. - 2008-06-25, 12:31

Join Date: Sep 2005
Posts: 314
Location: Finland, Helsinki
aaaaapo
Offline
Regular Contributor
Quote:
Originally Posted by y.a.k View Post
Just increase a global count variable in exitfunc() and if it reaches certain amount, don't call the lock.wait() but simply return, Python will close.
Thanks, this is what I ment.
Reply With Quote

#8 Old Re: Trick to prevent Python from closing on red key press. - 2008-06-26, 09:23

Join Date: Feb 2008
Posts: 63
blackpaw
Offline
Regular Contributor
Could there be issues with resource usage? multiple threads waiting on the lock?
Reply With Quote

#9 Old Re: Trick to prevent Python from closing on red key press. - 2008-06-26, 09:33

Join Date: Jun 2005
Posts: 382
y.a.k
Offline
Regular Contributor
First of all, they're not real threads, they're Active Objects. As for the lock, it seems that multiple Active Objects can wait for a single lock. No issues were observed. If I get some free time, I may look into the PyS60 sources and Ao_lock implementation and compare it with the Symbian reference to know for sure.
Reply With Quote

#10 Old Re: Trick to prevent Python from closing on red key press. - 2008-06-26, 09:34

Join Date: May 2007
Posts: 2,739
Location: 21.46 N 72.11 E
croozeus's Avatar
croozeus
Offline
Forum Nokia Champion
Quote:
Originally Posted by blackpaw View Post
Could there be issues with resource usage? multiple threads waiting on the lock?
I don't think that a single lock cannot handle multiple objects, so that not might be the issue here.

Best Regards,
Croozeus
Reply With Quote

#11 Old Re: Trick to prevent Python from closing on red key press. - 2008-06-28, 17:57

Join Date: Mar 2007
Posts: 153
novis
Offline
Regular Contributor
Hi guys,
I also tried y.a.ks Trick to prevent an pys60 app from closing.
I want to share my testing results with you for further discussion:

The test program is running a second threat.

After pressing the red hang-up key and comming back to the application my UI was still alive (which already was a sensation to me)
But I soon discovered that my second threat was (obviously) still in waiting mode.
Usualy my second threat delivers data every few seconds to a global variable, which I display on the screen. But here, there was no automatic screen refresh showing new data anymore.

The only way getting the latest data on the screen was to press the "options softkey" and then "cancel").
The result was a screen refresh with the latest set of data. (but still no automatic screen refresh anymore)

Unfortunately I'm still not familiar with the inner work of active objects, so I can only guess the problem:

Either: After comming back to the application the second threat was still in waiting mode

Or: something happend to my while-loop that I use in the main threat. Because here I check if there is new data from the second threat to refresh the screen.

thx
novis
Reply With Quote

#12 Old Re: Trick to prevent Python from closing on red key press. - 2008-06-28, 22:10

Join Date: Jun 2005
Posts: 382
y.a.k
Offline
Regular Contributor
Hmm, I'm not sure what happens in a multithreaded application. The question is: does Python kill the subthreads before it calls the sys.exitfunc or it waits until it returns? If the latter then we should be fine.

If, however, the trick works for single-thread apps only I have a suggestion for you. If you use a subthread just to update some value every couple of seconds, why not use an active object timer? Take a look at e32.Ao_timer class. And remember that it's much cheaper (resource-wise) to use an active object than a full fledged subthread. And you can use appuifw from them.
Reply With Quote

#13 Old Re: Trick to prevent Python from closing on red key press. - 2008-06-29, 11:08

Join Date: Mar 2007
Posts: 153
novis
Offline
Regular Contributor
Hi y.a.k,
the second thread is connecting to a server via socket to receive data every few seconds. The problemm having this in mainthread was, that my application screen was freezing as long as I was waiting for data.

Quote:
Take a look at e32.Ao_timer class. And remember that it's much cheaper (resource-wise) to use an active object than a full fledged subthread
I'll have a look at this, thx. If this is a way to work without freezing the application it would be fine. (For me the active object philosophy is still not fully clear.)


Quote:
The question is: does Python kill the subthreads before it calls the sys.exitfunc or it waits until it returns?
In my test application Python didn't kill the subthread. But as I mentioned earlier, it seemed that (after comming back to the app.) either the subthread or the mainthread was still on halt as the screen in the mainthread was not refreshed (which it usualy does on new incomming data from the subthread).

kind regards
novis
Reply With Quote

#14 Old Re: Trick to prevent Python from closing on red key press. - 2008-06-29, 11:41

Join Date: Jun 2005
Posts: 382
y.a.k
Offline
Regular Contributor
I see, if the thread sleeps waiting for data, having it in an active object will still cause freezes to the UI. You said that the thread downloads the data and sets a global variable which is then read by the main thread and displayed on screen. How do you tell the main thread to update this value? Maybe you could use the e32.Ao_timer to do this.
Reply With Quote

#15 Old Re: Trick to prevent Python from closing on red key press. - 2008-06-29, 13:00

Join Date: Mar 2007
Posts: 153
novis
Offline
Regular Contributor
Quote:
How do you tell the main thread to update this value? Maybe you could use the e32.Ao_timer to do this
It's very simple. As the global variable is known by the main- and the subthread (The subthread is writing and the mainthread is reading it)
The mainthread just checks if the value of the global variable is changing. If yes, then I initiate a screen refresh. In order to give both threads enought time for their work I use "e32.ao_sleep(0.1)" which is causing the Global Interpreter Lock to switch back to the other thread.
Reply With Quote
Reply « Previous Thread | Next Thread »
Display Modes
Thread Tools Search this Thread
Search this Thread:

Advanced Search
Rate This Thread
Rate This Thread:

Posting Rules

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

vB code is On
Smilies are On
[IMG] code is Off
HTML code is Off
Forum Jump
Similar Threads
Thread Thread Starter Forum Replies Last Post
Yucca please help: Long key press - iRepeats is never 1 Tasneem Rangwala General Symbian C++ 1 2009-10-28 04:32
End(red) Button in HandleWsEventL() ezchip General Symbian C++ 48 2009-04-28 12:46
how capture the long key press krgvs General Symbian C++ 1 2008-04-14 09:09
How to disable the red key for closing Python? carknue Python 3 2007-11-15 22:18
Prevent python getting closed by kernel prashanth_ym Python 2 2007-05-21 11:30

Rate This

 
Bookmark this page: DeliciousDiggFacebookGoogleYahooStumbleUponRedditDiigoTechnocratiTwitter  Share this page Share this page Print this Page Print this page Invite a friend Invite a friend
京ICP备05048969号    Email Newsletters Press Terms & Conditions Privacy Policy Sitemap Contact Us © 2009 Nokia