- 论坛徽章:
- 0
|
以下是一个简单的GTKdemo程序,在RedHat9.0(内核2.4.20)下运行正常,在Fedora-6(内核2.6.1 下,一旦从siglongjmp回到sigsetjmpGTK就不能响应按键事件,也就是说,key_handler不工作了。不能响应按键事件。百思不得其解,是否sigsetjmp函数在较高的内核版本上支持不好,请高手赐教!
#include <unistd.h>
#include <signal.h>
#include <setjmp.h>
#include <sys/time.h>
#include <stdlib.h>
#include <stdio.h>
#include <semaphore.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <gdk/gdkkeysyms.h>
#include <gtk/gtk.h>
#define WINDOW_W 320
#define WINDOW_H 240
/********************************************************************************************/
sigjmp_buf jmpbuffer;
static void sigalrm_handler(int signo)
{
siglongjmp(jmpbuffer, 1);
}
static void* run_thread(void *state_addr)
{
struct itimerval itv, oldtv;
itv.it_interval.tv_sec = 0;
itv.it_interval.tv_usec = 1000000/5;
itv.it_value.tv_sec = 0;
itv.it_value.tv_usec = itv.it_interval.tv_usec;
if(signal(SIGALRM, sigalrm_handler)==SIG_ERR)
perror("signal(alarm) error.\n" ;
if(sigsetjmp(jmpbuffer, 1)==0){
setitimer(ITIMER_REAL, &itv, &oldtv);
printf("%s: Sigsetjmp set here.\n", __FUNCTION__);
while(TRUE)
pause();
}
printf("%s: Alarm signal occured.\n", __FUNCTION__);
while(*(int*)state_addr){
pause();
printf("%s: Other signal occured.\n", __FUNCTION__);
}
itv.it_value.tv_sec = 0x7FFFFFFF;
setitimer(ITIMER_REAL, &itv, &oldtv);
if(signal(SIGALRM, SIG_DFL)==SIG_ERR)
perror("signal(alarm) error.\n" ;
return NULL;
}
static void key_handler(GtkWidget *widget, GdkEventKey *event, gpointer state_addr)
{
static pthread_t thread_id;
printf("@@@@%s: A key was pressed.\n", __FUNCTION__);
switch (event->keyval) {
case GDK_Escape:
if(*(int*)state_addr){
*(int*)state_addr = 0;
pthread_join(thread_id, NULL);
printf("%s: Thread out.\n", __FUNCTION__);
}
break;
case GDK_F1:
if(*(int*)state_addr)
return;
*(int*)state_addr = 1;
pthread_create(&thread_id, NULL, run_thread, state_addr);
printf("%s: Thread created.\n", __FUNCTION__);
break;
default:
break;
}
return;
}
static void run(void* state_addr)
{
GtkWidget *window;
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_decorated(GTK_WINDOW(window), FALSE);
gtk_window_set_default_size(GTK_WINDOW(window), WINDOW_W, WINDOW_H);
gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
gtk_widget_show_all(window);
g_signal_connect(G_OBJECT(window), "key_press_event", G_CALLBACK(key_handler), state_addr);
return;
}
int main(int argc, char *argv[])
{
int state=0;
gtk_init(&argc, &argv);
run(&state);
gtk_main();
return 0;
}
[ 本帖最后由 ericooler 于 2007-6-6 17:51 编辑 ] |
|