Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 23 Feb 1999 21:47:44 -0800
From:      John Plevyak <jplevyak@inktomi.com>
To:        hackers@FreeBSD.ORG
Subject:   flock and kernel threads
Message-ID:  <19990223214744.A24606@proxydev.inktomi.com>

next in thread | raw e-mail | index | archive | help


I believe there may be a problem with lockfiles (flock) and
kernel threads.  The problem is demonstrated by the enclosed
program, which if run twice will fail the second time.

The problem seems to be that termination via signal of
the non-main thread (non-leader) does not (always) result 
in a call to closef and hence a call to lf_clearlock.

Suggestions, comments welcome.

john

======================== CUT HERE ==============================

#include <sys/types.h>
#include <unistd.h>
#include <assert.h>
#include <stdio.h>
#include <signal.h>
#include <errno.h>
#include <fcntl.h>
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <pthread.h>

pthread_t ink_thread_create(void*(*f)(void *),void * a) {
  pthread_t t;
  int ret;

  pthread_attr_t attr;

  pthread_attr_init(&attr);
  pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);

  ret = pthread_create(&t, &attr, f, a);
  assert(!ret);

  pthread_attr_destroy(&attr);

  return t;
}

int lockfile_open (const char *lockfile, int *fd_ptr)
{
#define FAIL(x) \
{ \
  if (fd > 0) \
    close (fd); \
  return (x); \
}
  struct flock lock;
  int size;
  int val;
  int err;
  int fd;

  *fd_ptr = -1;

  // Try and open the lockfile. Create it if it does not already
  // exist.
  do {
    fd = open (lockfile, O_RDWR | O_CREAT, 0600);
  } while ((fd < 0) && (errno == EINTR));

  if (fd < 0)
    FAIL (-errno);

  // Lock it. Note that if we can't get the lock EAGAIN will be the
  // error we receive.
  lock.l_type = F_WRLCK;
  lock.l_start = 0;
  lock.l_whence = SEEK_SET;
  lock.l_len = 0;

  do {
    err = fcntl (fd, F_SETLK, &lock);
  } while ((err < 0) && (errno == EINTR));

  if (err < 0)
    FAIL(0);

  // Return the file descriptor of the opened lockfile. When this file
  // descriptor is closed the lock will be released.

  *fd_ptr = fd;
  return(1);  // success

#undef FAIL
}

void * dthread(void * a) {
  (void)kill(0, SIGKILL);
  // or (void)kill(getpid(), SIGKILL);
}

int main(int argc, char ** argv) {
  int fd, i;
  int res = lockfile_open("lockfile.lock", &fd);
  printf("res = %d, fd = %d\n", res, fd);
  if (!res) exit(0);
  ink_thread_create(dthread, 0);
  sleep(10);
}

======================== CUT HERE ==============================
-- 
John Bradley Plevyak,    PhD,    jplevyak@inktomi.com,     PGP KeyID: 051130BD
Inktomi Corporation,  1900 S. Norfolk Street,  Suite 110,  San Mateo, CA 94403
W:(415)653-2830 F:(415)653-2801 P:(888)491-1332/5103192436.4911332@pagenet.net


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-hackers" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?19990223214744.A24606>