GTK+ Forums

Discussion forum for GTK+ and Programming. Ask questions, troubleshoot problems, view and post example code, or express your opinions.
It is currently Tue Oct 21, 2014 2:13 am

All times are UTC




Post new topic Reply to topic  [ 1 post ] 
Author Message
 Post subject: Question about Signalhandler in GTK+2.0 and C
PostPosted: Fri May 16, 2008 4:43 pm 
Offline

Joined: Mon Apr 07, 2008 8:37 pm
Posts: 2
Hi,

I just have a unnormal behavier of my written code C code.
Maybe I just misunterstood something, so does anyone see my error?

I have installed a signalhandler right before the gtk_main() function. Inside this signalhandler, I read from a GPIO Device, and belonging to the information written inside the signalhandler, I call with " g_signal_emit_by_name( button_runter_event,"button_press_event", NULL, &signal_return);"

Sometimes my application just crash, with an error like this one:
Quote:
GLib: Cannot convert message: Conversion from character set 'UTF-8' to 'ASCII' is not supported

(gtk:398): GLib-GObject-CRITICAL **: g_object_get_qdata: assertion `G_IS_OBJECT (object)' failed
Segmentation fault

This is definitly caused by the signal handler, because if i use my mouse, it never happends.

Would it be possible, that because I interrupt gtk_main() and then send an signal to call a function, the application crashes?

This is my code belonging to the signalhandler:
Code:
#include <errno.h>
#include <fcntl.h>
#include <poll.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include "functions.h"

static int fd_gpio;
static unsigned long old_state, new_state;
sigset_t saved_mask;
sigset_t sigio_mask;

gboolean signal_return=false;


static void sigio_handler_gpio(int sig, siginfo_t *info, void *context);
static void evaluate_gpio( void );

int gpio_taster_init( void ){
   
   fd_gpio = open(GPIO_DEVICE, O_RDONLY);
   if (fd_gpio < 0) {
      fprintf(stderr, "failed to open %s: %s\n",
         GPIO_DEVICE, strerror(errno));
      return 1;
   }

   struct sigaction sigio_action = {
      .sa_sigaction = sigio_handler_gpio,
      .sa_flags = SA_SIGINFO,
   };
   int flags;

   // Don't mask any signals when handling SIGIO (except
   // SIGIO itself, which is masked by default.)
   sigemptyset(&sigio_action.sa_mask);
   if (sigaction(SIGIO, &sigio_action, NULL)) {
      perror("failed to install SIGIO handler");
      return 1;
   }

   // Tell the kernel that our process will take care of SIGIO
   if (fcntl(fd_gpio, F_SETOWN, getpid())) {
      perror("failed to set fd owner");
      return 1;
   }

   // Enable asynchronous I/O
   flags = fcntl(fd_gpio, F_GETFL);
   if (fcntl(fd_gpio, F_SETFL, flags | O_ASYNC) < 0) {
      perror("failed to set O_ASYNC");
      return 1;
   }

   if (read(fd_gpio, &old_state, sizeof(old_state)) < 0) {
      perror("failed to read initial pin state");
      return 1;
   }
   new_state = old_state;

   
   sigemptyset(&sigio_mask);
   sigaddset(&sigio_mask, SIGIO);

   return 0;
}

// This function will be called to evaluate pressed button
static void evaluate_gpio(){   
      if ( new_state != old_state && new_state < old_state ) {
         if( ((new_state&(1<<BUTTON1_PIN))>>BUTTON1_PIN)==0 )
            g_signal_emit_by_name( button_hoch_event,"button_press_event", NULL, &signal_return);
         else if( ((new_state&(1<<BUTTON2_PIN))>>BUTTON2_PIN)==0 )
            g_signal_emit_by_name( button_help_event,"button_press_event", NULL, &signal_return);
         else if( ((new_state&(1<<BUTTON3_PIN))>>BUTTON3_PIN)==0 )
            g_signal_emit_by_name( button4_event,"button_press_event", NULL, &signal_return);
         else if( ((new_state&(1<<BUTTON4_PIN))>>BUTTON4_PIN)==0 )
            g_signal_emit_by_name( button2_event,"button_press_event", NULL, &signal_return);
         else if( ((new_state&(1<<BUTTON5_PIN))>>BUTTON5_PIN)==0 )
            g_signal_emit_by_name( button_runter_event,"button_press_event", NULL, &signal_return);
         else if( ((new_state&(1<<BUTTON6_PIN))>>BUTTON6_PIN)==0 )
            g_signal_emit_by_name( button6_event,"button_press_event", NULL, &signal_return);
         else if( ((new_state&(1<<BUTTON7_PIN))>>BUTTON7_PIN)==0 )
            g_signal_emit_by_name( button8_event,"button_press_event", NULL, &signal_return);
         else if( ((new_state&(1<<BUTTON8_PIN))>>BUTTON8_PIN)==0 )
            g_signal_emit_by_name( button_info_event,"button_press_event", NULL, &signal_return);
         printf("Signal send\n");
      }
      old_state = new_state;

      usleep(10000);
}

// This handler will be called whenever, the pin state changes.
static void sigio_handler_gpio(int sig, siginfo_t *info, void *context){
   unsigned long pin_state;
   
   //sigprocmask(SIG_BLOCK, &sigio_mask, &saved_mask);

   // This should never fail as we
   // shouldn't be here if no new data is available.
   if (read(fd_gpio, &pin_state, sizeof(pin_state)) < 0)
      perror("read error in sigio_handler_gpio");
   else
      new_state = pin_state;
   evaluate_gpio();
   
   //sigprocmask(SIG_UNBLOCK, &sigio_mask, &saved_mask);
}


Thank you very much,
pcgeil


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 1 post ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 2 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group