my_lock.c
上传用户:romrleung
上传日期:2022-05-23
资源大小:18897k
文件大小:4k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /* Copyright (C) 2000-2003 MySQL AB
  2.    This program is free software; you can redistribute it and/or modify
  3.    it under the terms of the GNU General Public License as published by
  4.    the Free Software Foundation; either version 2 of the License, or
  5.    (at your option) any later version.
  6.    This program is distributed in the hope that it will be useful,
  7.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  8.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  9.    GNU General Public License for more details.
  10.    You should have received a copy of the GNU General Public License
  11.    along with this program; if not, write to the Free Software
  12.    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
  13. #include "mysys_priv.h"
  14. #include "mysys_err.h"
  15. #include <errno.h>
  16. #undef MY_HOW_OFTEN_TO_ALARM
  17. #define MY_HOW_OFTEN_TO_ALARM ((int) my_time_to_wait_for_lock)
  18. #ifdef NO_ALARM_LOOP
  19. #undef NO_ALARM_LOOP
  20. #endif
  21. #include <my_alarm.h>
  22. #ifdef __WIN__
  23. #include <sys/locking.h>
  24. #endif
  25. #ifdef __EMX__
  26. #define INCL_BASE
  27. #define INCL_NOPMAPI
  28. #include <os2emx.h>
  29. #endif
  30. #ifdef __NETWARE__
  31. #include <nks/fsio.h>
  32. #endif
  33. /* Lock a part of a file */
  34. int my_lock(File fd, int locktype, my_off_t start, my_off_t length,
  35.     myf MyFlags)
  36. {
  37. #ifdef HAVE_FCNTL
  38.   int value;
  39.   ALARM_VARIABLES;
  40. #endif
  41. #ifdef __NETWARE__
  42.   int nxErrno;
  43. #endif
  44.   DBUG_ENTER("my_lock");
  45.   DBUG_PRINT("my",("Fd: %d  Op: %d  start: %ld  Length: %ld  MyFlags: %d",
  46.    fd,locktype,(long) start,(long) length,MyFlags));
  47. #ifdef VMS
  48.   DBUG_RETURN(0);
  49. #else
  50.   if (my_disable_locking)
  51.     DBUG_RETURN(0);
  52. #if defined(__NETWARE__)
  53.   {
  54.     NXSOffset_t nxLength = length;
  55.     unsigned long nxLockFlags = 0;
  56.     if (length == F_TO_EOF)
  57.     {
  58.       /* EOF is interpreted as a very large length. */
  59.       nxLength = 0x7FFFFFFFFFFFFFFF;
  60.     }
  61.     if (locktype == F_UNLCK)
  62.     {
  63.       /* The lock flags are currently ignored by NKS. */
  64.       if (!(nxErrno= NXFileRangeUnlock(fd, 0L, start, nxLength)))
  65.         DBUG_RETURN(0);
  66.     }
  67.     else
  68.     {
  69.       if (locktype == F_RDLCK)
  70.       {
  71.         /* A read lock is mapped to a shared lock. */
  72.         nxLockFlags = NX_RANGE_LOCK_SHARED;
  73.       }
  74.       else
  75.       {
  76.         /* A write lock is mapped to an exclusive lock. */
  77.         nxLockFlags = NX_RANGE_LOCK_EXCL;
  78.       }
  79.       if (MyFlags & MY_DONT_WAIT)
  80.       {
  81.         /* Don't block on the lock. */
  82.         nxLockFlags |= NX_RANGE_LOCK_TRYLOCK;
  83.       }
  84.       if (!(nxErrno= NXFileRangeLock(fd, nxLockFlags, start, nxLength)))
  85.         DBUG_RETURN(0);
  86.     }
  87.   }
  88. #elif defined(__EMX__) || defined(OS2)
  89.    if (!_lock64( fd, locktype, start, length, MyFlags))
  90.     DBUG_RETURN(0);
  91. #elif defined(HAVE_LOCKING)
  92.   /* Windows */
  93.   {
  94.     my_bool error;
  95.     pthread_mutex_lock(&my_file_info[fd].mutex);
  96.     if (MyFlags & MY_SEEK_NOT_DONE)
  97.       VOID(my_seek(fd,start,MY_SEEK_SET,MYF(MyFlags & ~MY_SEEK_NOT_DONE)));
  98.     error= locking(fd,locktype,(ulong) length) && errno != EINVAL;
  99.     pthread_mutex_unlock(&my_file_info[fd].mutex);
  100.     if (!error)
  101.       DBUG_RETURN(0);
  102.   }
  103. #else
  104. #if defined(HAVE_FCNTL)
  105.   {
  106.     struct flock lock;
  107.     lock.l_type=   (short) locktype;
  108.     lock.l_whence= SEEK_SET;
  109.     lock.l_start=  (off_t) start;
  110.     lock.l_len=    (off_t) length;
  111.     if (MyFlags & MY_DONT_WAIT)
  112.     {
  113.       if (fcntl(fd,F_SETLK,&lock) != -1) /* Check if we can lock */
  114. DBUG_RETURN(0); /* Ok, file locked */
  115.       DBUG_PRINT("info",("Was locked, trying with alarm"));
  116.       ALARM_INIT;
  117.       while ((value=fcntl(fd,F_SETLKW,&lock)) && ! ALARM_TEST &&
  118.      errno == EINTR)
  119.       { /* Setup again so we don`t miss it */
  120. ALARM_REINIT;
  121.       }
  122.       ALARM_END;
  123.       if (value != -1)
  124. DBUG_RETURN(0);
  125.       if (errno == EINTR)
  126. errno=EAGAIN;
  127.     }
  128.     else if (fcntl(fd,F_SETLKW,&lock) != -1) /* Wait until a lock */
  129.       DBUG_RETURN(0);
  130.   }
  131. #else
  132.   if (MyFlags & MY_SEEK_NOT_DONE)
  133.     VOID(my_seek(fd,start,MY_SEEK_SET,MYF(MyFlags & ~MY_SEEK_NOT_DONE)));
  134.   if (lockf(fd,locktype,length) != -1)
  135.     DBUG_RETURN(0);
  136. #endif /* HAVE_FCNTL */
  137. #endif /* HAVE_LOCKING */
  138. #ifdef __NETWARE__
  139.   my_errno = nxErrno;
  140. #else
  141. /* We got an error. We don't want EACCES errors */
  142.   my_errno=(errno == EACCES) ? EAGAIN : errno ? errno : -1;
  143. #endif
  144.   if (MyFlags & MY_WME)
  145.   {
  146.     if (locktype == F_UNLCK)
  147.       my_error(EE_CANTUNLOCK,MYF(ME_BELL+ME_WAITTANG),my_errno);
  148.     else
  149.       my_error(EE_CANTLOCK,MYF(ME_BELL+ME_WAITTANG),my_errno);
  150.   }
  151.   DBUG_PRINT("error",("my_errno: %d (%d)",my_errno,errno));
  152.   DBUG_RETURN(-1);
  153. #endif /* ! VMS */
  154. } /* my_lock */