apr-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From gst...@locus.apache.org
Subject cvs commit: apr/file_io/unix flock.c Makefile.in
Date Wed, 29 Nov 2000 07:37:42 GMT
gstein      00/11/28 23:37:42

  Modified:    test     .cvsignore Makefile.in
               include  apr_file_io.h
               file_io/unix Makefile.in
  Added:       test     testflock.c
               file_io/unix flock.c
  Log:
  *) Add functions for file-level locking/unlocking.
  *) Add test program for the new functions.
  
  Revision  Changes    Path
  1.9       +1 -0      apr/test/.cvsignore
  
  Index: .cvsignore
  ===================================================================
  RCS file: /home/cvs/apr/test/.cvsignore,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -u -r1.8 -r1.9
  --- .cvsignore	2000/10/30 15:01:50	1.8
  +++ .cvsignore	2000/11/29 07:37:40	1.9
  @@ -23,3 +23,4 @@
   testsuite
   testsuite.opt
   testsuite.ncb
  +testflock.tmp
  
  
  
  1.27      +6 -1      apr/test/Makefile.in
  
  Index: Makefile.in
  ===================================================================
  RCS file: /home/cvs/apr/test/Makefile.in,v
  retrieving revision 1.26
  retrieving revision 1.27
  diff -u -u -r1.26 -r1.27
  --- Makefile.in	2000/11/15 11:50:10	1.26
  +++ Makefile.in	2000/11/29 07:37:40	1.27
  @@ -10,6 +10,7 @@
   
   TARGETS= testmd5@EXEEXT@ \
   	testfile@EXEEXT@ \
  +	testflock@EXEEXT@ \
   	testproc@EXEEXT@ \
   	testsock@EXEEXT@ \
   	testsf@EXEEXT@ \
  @@ -28,6 +29,7 @@
   
   OBJS= testmd5.o \
   	testfile.o \
  +	testflock.o \
   	testproc.o \
   	testsock.o \
   	testsf.o \
  @@ -53,6 +55,9 @@
   testfile@EXEEXT@: testfile.o
   	$(CC) $(CFLAGS) -o testfile@EXEEXT@ testfile.o $(LDFLAGS) 
   
  +testflock@EXEEXT@: testflock.o
  +	$(CC) $(CFLAGS) -o testflock@EXEEXT@ testflock.o $(LDFLAGS) 
  +
   testdso@EXEEXT@: testdso.o
   	$(CC) $(CFLAGS) --export-dynamic -fPIC testdso.o -o testdso@EXEEXT@ $(LDFLAGS) 
   
  @@ -101,7 +106,7 @@
   	$(CC) $(CFLAGS) -o testuuid@EXEEXT@ testuuid.o $(LDFLAGS)
   
   clean:
  -	$(RM) -f *.o *.a *.so $(TARGETS)
  +	$(RM) -f *.o *.a *.so $(TARGETS) testflock.tmp
   
   distclean: clean
   	-$(RM) -f Makefile
  
  
  
  1.1                  apr/test/testflock.c
  
  Index: testflock.c
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2000 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  /*
   * USAGE
   *
   * Start one process, no args, and place it into the background. Start a
   * second process with the "-r" switch to attempt a read on the file
   * created by the first process.
   *
   * $ ./testflock &
   * ...messages...
   * $ ./testflock -r
   * ...messages...
   *
   * The first process will sleep for 30 seconds while holding a lock. The
   * second process will attempt to grab it (non-blocking) and fail. It
   * will then grab it with a blocking scheme. When the first process' 30
   * seconds are up, it will exit (thus releasing its lock). The second
   * process will acquire the lock, then exit.
   */
  
  #include "apr_pools.h"
  #include "apr_file_io.h"
  #include "apr_time.h"
  #include "apr_general.h"
  #include "apr_getopt.h"
  #include "apr_strings.h"
  
  #include <stdlib.h>
  #include <stdio.h>
  
  #define TESTFILE "testfile.tmp"
  
  static apr_pool_t *pool = NULL;
  
  
  static void errmsg(const char *msg)
  {
      if (pool != NULL)
          apr_destroy_pool(pool);
      fprintf(stderr, msg);
      exit(1);
  }
  
  static void do_read(void)
  {
      apr_file_t *file;
      apr_status_t status;
  
      if (apr_open(&file, TESTFILE, APR_WRITE,
                   APR_OS_DEFAULT, pool) != APR_SUCCESS)
          errmsg("Could not open test file.\n");
      printf("Test file opened.\n");
  
      status = apr_lock_file(file, APR_FLOCK_EXCLUSIVE | APR_FLOCK_NONBLOCK);
      if (!APR_STATUS_IS_EAGAIN(status)) {
          char msg[200];
          errmsg(apr_psprintf(pool, "Expected EAGAIN. Got %d: %s.\n",
                              status, apr_strerror(status, msg, sizeof(msg))));
      }
      printf("First attempt: we were properly locked out.\nWaiting for lock...");
      fflush(stdout);
  
      if (apr_lock_file(file, APR_FLOCK_EXCLUSIVE) != APR_SUCCESS)
          errmsg("Could not establish lock on test file.");
      printf(" got it.\n");
  
      (void) apr_close(file);
      printf("Exiting.\n");
  }
  
  static void do_write(void)
  {
      apr_file_t *file;
  
      if (apr_open(&file, TESTFILE, APR_WRITE|APR_CREATE, APR_OS_DEFAULT,
                   pool) != APR_SUCCESS)
          errmsg("Could not create file.\n");
      printf("Test file created.\n");
  
      if (apr_lock_file(file, APR_FLOCK_EXCLUSIVE) != APR_SUCCESS)
          errmsg("Could not lock the file.\n");
      printf("Lock created.\nSleeping...");
      fflush(stdout);
  
      apr_sleep(30000000);        /* 30 seconds */
  
      (void) apr_close(file);
      printf(" done.\nExiting.\n");
  }
  
  int main(int argc, const char * const *argv)
  {
      int reader = 0;
      apr_status_t status;
      char optchar;
      const char *optarg;
      apr_getopt_t *opt;
  
      if (apr_initialize() != APR_SUCCESS)
          errmsg("Could not initialize APR.\n");
      atexit(apr_terminate);
  
      if (apr_create_pool(&pool, NULL) != APR_SUCCESS)
          errmsg("Could not create global pool.\n");
  
      if (apr_initopt(&opt, pool, argc, argv) != APR_SUCCESS)
          errmsg("Could not parse options.\n");
  
      while ((status = apr_getopt(opt, "r", &optchar, &optarg)) == APR_SUCCESS) {
          if (optchar == 'r')
              ++reader;
      }
  
      if (reader)
          do_read();
      else
          do_write();
  
      return 0;
  }
  
  
  
  1.76      +38 -1     apr/include/apr_file_io.h
  
  Index: apr_file_io.h
  ===================================================================
  RCS file: /home/cvs/apr/include/apr_file_io.h,v
  retrieving revision 1.75
  retrieving revision 1.76
  diff -u -u -r1.75 -r1.76
  --- apr_file_io.h	2000/11/26 03:51:45	1.75
  +++ apr_file_io.h	2000/11/29 07:37:41	1.76
  @@ -59,8 +59,9 @@
   #include "apr_pools.h"
   #include "apr_time.h"
   #include "apr_errno.h"
  +
   #if APR_HAVE_STDIO_H
  -#include <stdio.h>
  +#include <stdio.h>      /* for SEEK_* */
   #endif
   
   #ifdef __cplusplus
  @@ -163,6 +164,23 @@
       apr_time_t ctime;
   };
   
  +/** File lock types/flags */
  +#define APR_FLOCK_SHARED        1       /* Shared lock. More than one process
  +                                           or thread can hold a shared lock
  +                                           at any given time. Essentially,
  +                                           this is a "read lock", preventing
  +                                           writers from establishing an
  +                                           exclusive lock. */
  +#define APR_FLOCK_EXCLUSIVE     2       /* Exclusive lock. Only one process
  +                                           may hold an exclusive lock at any
  +                                           given time. This is analogous to
  +                                           a "write lock". */
  +
  +#define APR_FLOCK_TYPEMASK      0x000F  /* mask to extract lock type */
  +#define APR_FLOCK_NONBLOCK      0x0010  /* do not block while acquiring the
  +                                           file lock */
  +
  +
   /*   Make and Merge Canonical Name Options */
   
   /**
  @@ -616,6 +634,25 @@
    *        forever, 0 means do not wait at all.
    */
   apr_status_t apr_set_pipe_timeout(apr_file_t *thepipe, apr_interval_time_t timeout);
  +
  +/** file (un)locking functions. */
  +
  +/**
  + * Establish a lock on the specified, open file. The lock may be advisory
  + * or mandatory, at the discretion of the platform. The lock applies to
  + * the file as a whole, rather than a specific range. Locks are established
  + * on a per-thread/process basis; a second lock by the same thread will not
  + * block.
  + * @param thefile The file to lock.
  + * @param type The type of lock to establish on the file.
  + */
  +apr_status_t apr_lock_file(apr_file_t *thefile, int type);
  +
  +/**
  + * Remove any outstanding locks on the file.
  + * @param thefile The file to unlock.
  + */
  +apr_status_t apr_unlock_file(apr_file_t *thefile);
   
   /**accessor and general file_io functions. */
   
  
  
  
  1.20      +1 -0      apr/file_io/unix/Makefile.in
  
  Index: Makefile.in
  ===================================================================
  RCS file: /home/cvs/apr/file_io/unix/Makefile.in,v
  retrieving revision 1.19
  retrieving revision 1.20
  diff -u -u -r1.19 -r1.20
  --- Makefile.in	2000/11/15 11:49:46	1.19
  +++ Makefile.in	2000/11/29 07:37:41	1.20
  @@ -14,6 +14,7 @@
   	fileacc.o \
   	filedup.o \
   	filestat.o \
  +	flock.o \
   	fullrw.o \
   	open.o \
   	pipe.o \
  
  
  
  1.1                  apr/file_io/unix/flock.c
  
  Index: flock.c
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2000 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  #include "fileio.h"
  
  #ifdef HAVE_FCNTL_H
  #include <fcntl.h>
  #endif
  #ifdef HAVE_SYS_FILE_H
  #include <sys/file.h>
  #endif
  
  apr_status_t apr_lock_file(apr_file_t *thefile, int type)
  {
      int rc;
  
  #if defined(HAVE_FCNTL_H)
      {
          struct flock l = { 0 };
          int fc;
  
          l.l_whence = SEEK_SET;  /* lock from current point */
          l.l_start = 0;          /* begin lock at this offset */
          l.l_len = 0;            /* lock to end of file */
          if ((type & APR_FLOCK_TYPEMASK) == APR_FLOCK_SHARED)
              l.l_type = F_RDLCK;
          else
              l.l_type = F_WRLCK;
  
          fc = (type & APR_FLOCK_NONBLOCK) ? F_SETLK : F_SETLKW;
  
          /* keep trying if fcntl() gets interrupted (by a signal) */
          while ((rc = fcntl(thefile->filedes, fc, &l)) < 0 && errno ==
EINTR)
              continue;
  
          if (rc == -1)
              return errno;
      }
  #elif defined(HAVE_SYS_FILE_H)
      {
          int ltype;
  
          if ((type & APR_FLOCK_TYPEMASK) == APR_FLOCK_SHARED)
              ltype = LOCK_SH;
          else
              ltype = LOCK_EX;
          if ((type & APR_FLOCK_NONBLOCK) != 0)
              ltype |= LOCK_NB;
  
          /* keep trying if flock() gets interrupted (by a signal) */
          while ((rc = flock(thefile->filedes, ltype)) < 0 && errno == EINTR)
              continue;
  
          if (rc == -1)
              return errno;
      }
  #else
  #error No file locking mechanism is available.
  #endif
  
      return APR_SUCCESS;
  }
  
  apr_status_t apr_unlock_file(apr_file_t *thefile)
  {
      int rc;
  
  #if defined(HAVE_FCNTL_H)
      {
          struct flock l = { 0 };
  
          l.l_whence = SEEK_SET;  /* lock from current point */
          l.l_start = 0;          /* begin lock at this offset */
          l.l_len = 0;            /* lock to end of file */
          l.l_type = F_UNLCK;
  
          /* keep trying if fcntl() gets interrupted (by a signal) */
          while ((rc = fcntl(thefile->filedes, F_SETLKW, &l)) < 0
                 && errno == EINTR)
              continue;
  
          if (rc == -1)
              return errno;
      }
  #elif defined(HAVE_SYS_FILE_H)
      {
          /* keep trying if flock() gets interrupted (by a signal) */
          while ((rc = flock(thefile->filedes, LOCK_UN)) < 0 && errno == EINTR)
              continue;
  
          if (rc == -1)
              return errno;
      }
  #else
  #error No file locking mechanism is available.
  #endif
  
      return APR_SUCCESS;
  }
  
  
  

Mime
View raw message