English | 中文 | Русский | Français
2,556 Posts served
8,264 Conversations started
Well, it has been a while since I wrote a blog entry, but boy have I learned some stuff! If you have followed my previous blogs you know that I have been working on developing a program to be run on MIDs. I started out putting together my development system and creating my program in Linux. Then I started working on learning about moblin.org and going through the tutorials there on creating a target and additional things that are needed to run a program on MIDs. Just after I wrote my last blog I ran into a problem that has been the bane of my existence for a while. The problem was a segmentation fault that has been erratic and difficult to pin down. Remember my problem and solution from my first blog? I fixed the error and the program worked, but I kept getting the warning: says "Glib-WARNING **: g_main_context_prepare(): main loop already active in another thread." Well, I'm happy to tell you that I have cleared up the warning and it is kind of related to the segmentation fault I was getting. But, let's start at the beginning.
I wasn't able to find very much to help me on the warning so for a while I just lived with it. I kept trying different things to help relieve it. I tried putting in a pthread mutex and locking and unlocking between the call I made in the signal handler. That didn't fix it. Then I found out about gdk_threads_enter() and gdk_threads_leave() and tried those in the signal handler in the main thread. I couldn't get the g_thread_init(NULL) call to work inside the main thread. Then, finally I tried putting the init functions in a thread other than the main GUI thread and I was able to do that. After reading some more at the GDK Reference Manual I realized that the function I added was a GTK+ function which cannot be called from another thread without the gdk_threads_enter() and gdk_threads_leave() functions being used. What I ended up doing is putting the "enter" and "leave" functions in the second thread around the function call that updated data in the main thread. It worked! By doing this, I found I didn't even need the GTK+ function forcing a refresh in the signal handler. The data was updated right away. Whew!
But, while that was nice to have cleared up, I had uncovered another problem. A segmentation fault was driving me nuts. One of the main features of my application was the use of the DBus system to receive information about the MID system. DBus is a system designed and used for interprocess communication in most Linux systems. There are defined calls to be made and quite a few tutorials on the web. The major tutorial seems to be D-Bus Tutorial. All of my DBus calls were made on one particular thread, which makes sense. Except that sometimes when I was running the program it would have a segmentation fault and the program would crash. At first, it was happening about 1 out of every 3 or 4 times. I had a friend who is a long-time coder take a look at the code. He pointed out some areas I needed to tighten up and I gladly took his recommendations and made the changes. The segmentation fault was still there. I had some of the other software engineers take a look at the code. They also had some recommendations, most of which I agreed with and implemented. The segmentation fault still came and went at will (it seemed to almost take on a life of its own). We had a group look and talk session to see if together we could find it. Apparently, we couldn't. The group did recommend that I load up a tool called Klocwork which is a bug analysis tool. Klocwork found 5 minor problems which I fixed, but the fixes did not result in the segmentation fault disappearing. Finally, I took the code home with me and remove the DBus code from the threaded environment. I made a simple GUI and ran the DBus code in single thread mode. No segmentation fault over 80 iterations. Then I created a second thread and put the DBus code in the second thread. Guess what? The segmentation fault was back. Have you already figured out what the solution was? Yes, the gdk_threads_enter() and gdk_threads_leave() functions! By surrounding the DBus calls with those two functions, my program runs without any crashes at all. Looking back, most of the "code monkeys" I asked to look at my code had never written code in the Linux environment, so it is not too surprising that they weren't familiar with GTK+ critical section needs.
My program is now going through code inspection, and I don't expect it to be a difficult experience at all, since so many people have already given me their suggestions and tips. My last big hurdle is to actually get my program running on an actual MID. We have received some MIDs to use as test vehicles so I have the hardware I need. Will there be another adventure while actually getting the program into the MID? Stay tuned, friends and neighbors, and I'll let you know soonest.
| October 2, 2008 9:47 AM PDT
Judy Hartley (Intel)
|
Hi Steve, No, I'm doing my UI in the main thread, but some information from the other threads needs to be inserted into the GUI widgets. I have a pointer to the main thread in my second thread but in order to use it the gdk_threads_enter() and gdk_threads_leave() have to surround that pointer call to a function in the GUI (main) thread that puts the new information into the widget box. The main thread is a GTK::Window thread, so that's why I have to put locks around the second thread's call. I hope that makes it a little clearer. Cheers, |

Steve
Usually I would do the UI in my main thread and spin off worker threads for the work.
Would that have avoided the problem?
Anyways, if you're only calling GTK functions from one thread I don't see why you'd need to worry about critical sections at all.