contentLister/src/erConnect.c File Reference

connect finite state machine and process launcher More...

#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <gtk/gtk.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/time.h>
#include <time.h>
#include <liberdm/display.h>
#include <liberregxml/erregapi.h>
#include <libermanifest/ermanifest.h>
#include "contentListerLog.h"
#include "button.h"
#include "erConnect.h"
#include "erMSDisk.h"
#include "system.h"
#include "gtkPincodeScreen.h"
#include "control.h"
#include "programManager.h"
#include "regValue.h"
#include "toolbar.h"
#include "timedids.h"

Go to the source code of this file.

Defines

#define KILL_TIMEOUT   5*1000*1000
#define timerclear(tvp)   ((tvp)->tv_sec = (tvp)->tv_usec = 0)

Functions

static void * connectThread (void *arg)
void erConnectInit (connectStruct_t *connect)
pid_t erConnectPid (void)

Variables

static pid_t g_connect_pid = 0


Detailed Description

connect finite state machine and process launcher

<File description>="">

Definition in file erConnect.c.


Define Documentation

#define KILL_TIMEOUT   5*1000*1000

Definition at line 60 of file erConnect.c.

#define timerclear ( tvp   )     ((tvp)->tv_sec = (tvp)->tv_usec = 0)

Definition at line 61 of file erConnect.c.


Function Documentation

static void * connectThread ( void *  arg  )  [static]

Definition at line 109 of file erConnect.c.

00110 {
00111     connectStruct_t *connect = (connectStruct_t *) arg;
00112     struct timeval tv_kill, tv;
00113     unsigned int stop = 0;// a flag to indicate whether connectThread receives connectCmdStop
00114     unsigned int first = 1;// aflag to indicate this is the first time we send SIGKILL
00115 
00116     CL_CTPRINTF("enter");
00117 
00118     pthread_mutex_lock( &(connect->mutex) );
00119 
00120     CL_CTPRINTF("enter active part");
00121     // initialize timevals
00122     timerclear(&tv_kill);
00123     timerclear(&tv);
00124 
00125     while (1)
00126     {
00127         switch (connect->state)
00128         {
00129             case connectStateIdle:
00130             {
00131                 if (connect->command == connectCmdStart)
00132                 {
00133                     CL_CTPRINTF("connectCmdStart");
00134                     connect->command = connectCmdNone;
00135 
00136                     switch (g_connect_pid = fork())
00137                     {
00138                         case 0:
00139                         {
00140                             // child process
00141                             int     nRet;
00142 
00143                             CL_WARNPRINTF("Calling: [%s]", connect->szCommand);
00144                             nRet = shell_exec(connect->szCommand);
00145                             CL_ERRORPRINTF("shell_exec of [%s] failed (returned [%d]), " 
00146                                            "cleaning up child\n", connect->szCommand, nRet);
00147                             perror("Error upon calling shell_exec");
00148                             fflush(stderr);
00149                             exit(1);
00150                             break;
00151                         }
00152                             
00153                         case -1:
00154                             // error
00155                             CL_ERRORPRINTF("Can't fork");
00156                             connect->state = connectStateDisconnected;
00157                             break;
00158 
00159                         default:
00160                             // parent process
00161                             connect->state = connectStateConnected;
00162                     }
00163                 }
00164                 else if (connect->command == connectCmdNone)
00165                 {
00166                     // nothing to do -> wait for next command
00167                     CL_CTPRINTF("connectCmdNone");
00168                     pthread_mutex_lock( &(connect->mutex) );
00169                     // initialize these flags
00170                     stop = 0;
00171                     first = 1;
00172                     // initialize timevals
00173                     timerclear(&tv_kill);
00174                     timerclear(&tv);
00175                 }
00176                 else
00177                 {
00178                     CL_ERRORPRINTF("unexpected connectCmd [%d]", connect->command);
00179                     connect->command = connectCmdNone;
00180                 }
00181                 break;
00182             }// case connectStateIdle
00183 
00184             case connectStateConnected:
00185             {
00186                 pid_t   retPid;
00187                 int     status;
00188 
00189                 if (connect->command == connectCmdStop)
00190                 {
00191                     CL_CTPRINTF("connectCmdStop: pid [%d]", g_connect_pid);
00192                     connect->command = connectCmdNone;
00193 
00194                     if (kill(g_connect_pid, SIGTERM) == -1)
00195                     {
00196                         CL_ERRORPRINTF("Failed to stop downloadMgr");
00197                         perror("Error in kill");
00198                         connect->state = connectStateDisconnected;
00199                     }
00200                     // store the time when killing connectionMgr and downloadMgr
00201                     gettimeofday(&tv_kill, NULL);
00202                     // set the 'stop' flag to be 1
00203                     stop = 1;
00204 
00205                     break;
00206                 }
00207 
00208                 // Child process still alive ...
00209                 retPid = waitpid(g_connect_pid, &status, WNOHANG);
00210                 if (retPid == 0)
00211                 {
00212                     CL_CTPRINTF("connectionMgr alive");
00213                     
00214                     unsigned int kill_force = 0;
00215                     // check whether we need to killall -9 connectionMgr
00216                     if (stop)
00217                     {
00218                         gettimeofday(&tv, NULL);
00219                         suseconds_t time_diff = ((tv.tv_sec - tv_kill.tv_sec) * 1000 * 1000) + (tv.tv_usec - tv_kill.tv_usec);
00220                         if (time_diff > KILL_TIMEOUT) { kill_force = 1; }
00221                         CL_CTPRINTF("elapsed %d suseconds_t", (int)time_diff);
00222                     }
00223                    
00224                     if (first && kill_force)
00225                     {
00226                         // need to killall -9 connectionMgr
00227                         CL_CTPRINTF("Sending 'SIGKILL' to stop connectionMgr.");
00228                         // set the flag to ensure we only run killall -9 once
00229                         first = 0;
00230                         if (kill(g_connect_pid, SIGKILL) == -1)
00231                         {
00232                             CL_ERRORPRINTF("Failed to kill -9 connectionMgr");
00233                             perror("Error in kill");
00234                             connect->state = connectStateDisconnected;
00235                         }
00236                     }
00237                     else
00238                     {
00239                         // ... yes -> check again later
00240                         CL_CTPRINTF("check again later");
00241                         sleep(1);
00242                     }
00243                 }
00244                 else
00245                 {
00246                     // ... no -> we are disconnected
00247                     connect->state = connectStateDisconnected;
00248                 }
00249                 break;
00250             }// connectStateConnected
00251 
00252             case connectStateDisconnected:
00253             {
00254                 CL_CTPRINTF( "connectStateDisconnected: background [%d] after_reboot [%d] screen [%d]",
00255                              connect->background, connect->connect_after_reboot, connect->screen       );
00256                 connect->state = connectStateIdle;
00257 
00258                 gdk_threads_enter();
00259                 ctrl_cleanup_download_history();
00260                 ctrl_background_connect_timeout_start(FALSE);
00261                 ctrl_set_connect_icon();
00262                 if ( connect->background )
00263                 {
00264                     if (getListerState() != STATE_PINCODE)
00265                     {
00266                         erStartMSDiskApp();
00267                     }
00268                     toolbar_synchronise();
00269                 }
00270                 else
00271                 {
00272                     if (connect->connect_after_reboot)
00273                     {
00274                         setListerState(STATE_NORMAL);
00275                         pm_setUaOnTop(CONTENTLISTER_UAID);
00276                         toolbar_restore();
00277                         ctrl_startup();
00278                     }
00279                     else if (connect->connect_from_pincode)
00280                     {
00281                         // if users press connect button at pincode screen , 
00282                         // after finishing connected and downloaded, we need return
00283                         // back to pincode screen, not download history
00284                         ctrl_connect_back_to_pincode_screen();
00285                     }
00286                     else
00287                     {
00288                         setListerState(STATE_NORMAL);
00289                         erStartMSDiskApp();
00290                         toolbar_restore();
00291 
00292                         switch (connect->screen)
00293                         {
00294                             case connectScrUnchanged:
00295                                 CL_CTPRINTF("connectScrUnchanged");
00296                                 pm_setUaOnTop(CONTENTLISTER_UAID);
00297                                 break;
00298                             case connectScrMode:
00299                                 ctrl_mode_button_clicked();
00300                                 break;
00301                             case connectScrNews:
00302                                 ctrl_contentType_button_clicked(st_ContentTypeNews);
00303                                 break;
00304                             case connectScrBooks:
00305                                 ctrl_contentType_button_clicked(st_ContentTypeBooks);
00306                                 break;
00307                             case connectScrDocs:
00308                                 ctrl_contentType_button_clicked(st_ContentTypeDocs);
00309                                 break;
00310                             case connectScrNotes:
00311                                 ctrl_contentType_button_clicked(st_ContentTypeNotes);
00312                                 break;   
00313                            default:
00314                                 ctrl_display_download_history();
00315                                 break;
00316                         }// switch (connect->screen)
00317                     }// if (!connect->connect_from_pincode)
00318                 }// if ( !connect->background )
00319                 gdk_threads_leave();
00320                 break;
00321             }// connectStateDisconnected
00322 
00323             default:
00324             {
00325                 CL_CTPRINTF("unexpected state [%d]", connect->state);
00326                 connect->state = connectStateIdle;
00327             }
00328         }// state
00329     }// while
00330 
00331     pthread_exit(NULL);
00332 }

Here is the call graph for this function:

void erConnectInit ( connectStruct_t connect  ) 

Definition at line 70 of file erConnect.c.

00071 {
00072     connect->command              = connectCmdNone;
00073     connect->state                = connectStateIdle;
00074     connect->screen               = connectScrDownloadHistory;
00075     connect->background           = FALSE;
00076     connect->connect_from_pincode = FALSE;
00077     connect->connect_after_reboot = FALSE;
00078     connect->szCommand[0]         = '\0';
00079 
00080     if (pthread_mutex_init(&(connect->mutex), NULL) )
00081     {
00082         CL_ERRORPRINTF("Could not initialize connect mutex");
00083         perror("Could not initialize mutex");
00084     }
00085     else
00086     {
00087         CL_ERRORPRINTF("Lock the connect mutex");
00088         pthread_mutex_lock( &(connect->mutex) );
00089     }
00090 
00091     // Start the download thread
00092     pthread_t thread_id;
00093     if (pthread_create(&thread_id, NULL, connectThread, (void *) connect) != 0)
00094     {
00095         CL_CTPRINTF("%s %s: ", __FILE__, __FUNCTION__);
00096         perror("Could not create thread\n");
00097     }
00098 
00099     timed_ids_init();
00100 }

Here is the call graph for this function:

pid_t erConnectPid ( void   ) 

Definition at line 102 of file erConnect.c.

00103 {
00104     return g_connect_pid;
00105 }


Variable Documentation

pid_t g_connect_pid = 0 [static]

Definition at line 64 of file erConnect.c.


Generated on Sun Dec 14 17:13:23 2008 by  doxygen 1.5.6