Re: race condition without multiple threads?



On Tue, Apr 13, 2004 at 11:28:58PM +0200, Karl H. Beckers wrote:
Hi all,

am having this problem with a segfault that's been nagging me for days
appearing after some streamlining of completely unrelated code.

Hello,

If I were you I should get rid of all threads all to gether. Unix
has good process communication stuff in from the beginning. Making
many threads in the UI is just complicated. Let the UI "hang" on 
input (from file descritors) and take care of just "events". Let
dataprocessing happen in separate processes. If you want to look into
some nice process communication facility take a look att kqueue.

Since you can look for "events" on any file descriptor you can
easily do lengthy jobs in separate processes and just notify the
UI when it needs to take action.

Göran Hasse

---< Just a hack of example of kqueue >------------------

/**********************************************************************
 *
 *  $Id: ReadRecord.c,v 1.5 2004/03/29 21:53:32 gh Exp $
 *
 *  This program reads new data placed on a file
 *
 **********************************************************************/

#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/event.h>
#include <sys/time.h>
#include <sys/file.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/uio.h>
#include <unistd.h>
#include <errno.h>
#include <time.h>
#include <regex.h>

main(int argc, char *argv[]) 
{

  char buffer[1024];
  char mystring[1024];

  regex_t my_reg;
  regmatch_t pmatch[200];

  struct stat old_info, new_info;
  int old_size=0;
  int new_size=0;
  struct kevent ev;
  struct timespec nullts = {0 ,0};
  int fd;
  int tmpfile;
  int kq;
  int ret = 0;
  size_t nmatch;


  int n = 0;
  char tmpname[] = "/tmp/tmpXXXXXXXXXX";

  regcomp( &my_reg, "Nisse", REG_BASIC );


  /* Open an existing file */
  if ( ( fd = open( argv[1] , O_RDONLY ) ) == -1  )
    {
      printf("Fel när filen skulle öppnas\n");
      exit(1);
    } else {
      printf("Fildescriptor: %d on name %s\n", fd, argv[1] );
      fstat( fd , &old_info );
      printf("File size: %d\n", old_info.st_size );
    }

  /* Create kernel queue */
  kq = kqueue();

  ev.ident = fd;

  ev.filter = EVFILT_VNODE;

  ev.flags = EV_ADD | EV_ENABLE | EV_CLEAR;

  ev.fflags = NOTE_RENAME | NOTE_WRITE |
    NOTE_DELETE | NOTE_ATTRIB;

  /* Register events */
 
  kevent( kq, &ev, 1, NULL, 0, &nullts );
  printf("After register events\n");

  /* Check for events on the file */
  for(;;) {

    //printf("Before kevent\n");

    n = kevent(kq, NULL, 0,
               &ev, 1, NULL );

    if ( n > 0 ) {

      //printf("The file was");
      if(ev.fflags & NOTE_RENAME )
        printf( " renamed\n");
      if(ev.fflags & NOTE_WRITE ) {

        bzero( buffer, 1024);
        //printf( "File written to\n");
        /* Read the new data */
        fstat( fd, &new_info );
        lseek( fd, old_info.st_size , SEEK_SET);
        read( fd, buffer, new_info.st_size - old_info.st_size); 
        printf( "Size: %d\n", new_info.st_size - old_info.st_size); 
        printf( "%s" , buffer); 


        ret = regexec( &my_reg, buffer, nmatch, pmatch, REG_NOTBOL );
        printf("Retur: %d \n", ret );

        if( ret == 0 ) {

          /* Do som usefull things with the data */
          /* Write a mail... */

          strcpy( tmpname, "/tmp/tmpXXXXXXXXXX");
          tmpfile = mkstemp( tmpname );
          //printf("Name %s\n", tmpname );
          write( tmpfile, buffer, new_info.st_size - old_info.st_size); 

        
          bzero( mystring, 1024 );
          strcat( mystring, "/usr/bin/mail -stest root localhost < ");
          strcat( mystring, tmpname);

          printf("String: %s\n", mystring );

          // We do not whant this mail... ;-)
          //system( mystring );

          sleep(1);

          close( tmpfile );
          unlink( tmpname );

        }

        fflush(stdout);

        /* Remember the filezise */
          old_info = new_info;

      }

      if(ev.fflags & NOTE_DELETE )
        printf( " deleted\n");
      if(ev.fflags & NOTE_ATTRIB )
        printf( " chmodad\n");

    }

  }
}

/**********************************************************************
 *  EOF
 **********************************************************************/

---< snipp >------------------


-- 
Göran Hasse

----------------------------------------------------------------
Göran Hasse            email: gh raditex se     Tel: 08-6949270
Raditex AB             http://www.raditex.se    Fax: 08-4420570
Sickla Alle 7, 1tr                              Mob: 070-5530148
131 34  NACKA, SWEDEN





[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]