SQLite

Check-in [8ecae0943b]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Change the way threadsOverrideEachOthersLocks() works to avoid trying to write-lock a (potentially) read-only files. Also, assume that on non-linux systems threads do override each others locks. Ticket #3472. (CVS 5883)
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 8ecae0943b06102fe22133db0dcaf58ecbd39545
User & Date: danielk1977 2008-11-11 18:34:35.000
Context
2008-11-11
18:43
Remove some asserts that refer to variables removed in (5830). (CVS 5884) (check-in: 9d880a6fd2 user: danielk1977 tags: trunk)
18:34
Change the way threadsOverrideEachOthersLocks() works to avoid trying to write-lock a (potentially) read-only files. Also, assume that on non-linux systems threads do override each others locks. Ticket #3472. (CVS 5883) (check-in: 8ecae0943b user: danielk1977 tags: trunk)
18:28
Cleanup in flattenSubquery. Add OOM tests for flattenSubquery. Fix issues with OOM errors causes problems for flattenSubquery. Ticket #3485. (CVS 5882) (check-in: ea5f4baa04 user: drh tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/os_unix.c.
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
******************************************************************************
**
** This file contains code that is specific to Unix systems.
**
** $Id: os_unix.c,v 1.208 2008/11/07 00:06:18 drh Exp $
*/
#include "sqliteInt.h"
#if SQLITE_OS_UNIX              /* This file is used on unix only */

/*
** If SQLITE_ENABLE_LOCKING_STYLE is defined and is non-zero, then several
** alternative locking implementations are provided:







|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
******************************************************************************
**
** This file contains code that is specific to Unix systems.
**
** $Id: os_unix.c,v 1.209 2008/11/11 18:34:35 danielk1977 Exp $
*/
#include "sqliteInt.h"
#if SQLITE_OS_UNIX              /* This file is used on unix only */

/*
** If SQLITE_ENABLE_LOCKING_STYLE is defined and is non-zero, then several
** alternative locking implementations are provided:
489
490
491
492
493
494
495

496

497
498
499
500
501



502
503
504
505
506
507
508
509
510
511
512
513
514
515

516

517
518
519
520
521
522
523
524
525
526



527

528
529
530
531
532
533








534
535


536
537
538
539
540
541
542
  }
  errno = savedErrno;
  return s;
}
#define fcntl lockTrace
#endif /* SQLITE_LOCK_TRACE */


/*

** The testThreadLockingBehavior() routine launches two separate
** threads on this routine.  This routine attempts to lock a file
** descriptor then returns.  The success or failure of that attempt
** allows the testThreadLockingBehavior() procedure to determine
** whether or not threads can override each others locks.



*/
static void *threadLockingTest(void *pArg){
  struct threadTestData *pData = (struct threadTestData*)pArg;
  pData->result = fcntl(pData->fd, F_SETLK, &pData->lock);
  return pArg;
}

/*
** This procedure attempts to determine whether or not threads
** can override each others locks then sets the 
** threadsOverrideEachOthersLocks variable appropriately.
*/
static void testThreadLockingBehavior(int fd_orig){
  int fd;

  struct threadTestData d[2];

  pthread_t t[2];

  fd = dup(fd_orig);
  if( fd<0 ) return;
  memset(d, 0, sizeof(d));
  d[0].fd = fd;
  d[0].lock.l_type = F_RDLCK;
  d[0].lock.l_len = 1;
  d[0].lock.l_start = 0;
  d[0].lock.l_whence = SEEK_SET;



  d[1] = d[0];

  d[1].lock.l_type = F_WRLCK;
  pthread_create(&t[0], 0, threadLockingTest, &d[0]);
  pthread_create(&t[1], 0, threadLockingTest, &d[1]);
  pthread_join(t[0], 0);
  pthread_join(t[1], 0);
  close(fd);








  threadsOverrideEachOthersLocks =  d[0].result==0 && d[1].result==0;
}


#endif /* SQLITE_THREADSAFE */

/*
** Release a lockInfo structure previously allocated by findLockInfo().
*/
static void releaseLockInfo(struct lockInfo *pLock){
  if( pLock ){







>

>
|
<
<
|
|
>
>
>
|


|










>
|
>
|



|
<
|
|
|
|
>
>
>
|
>
|
|
<
|
<

>
>
>
>
>
>
>
>
|

>
>







489
490
491
492
493
494
495
496
497
498
499


500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526

527
528
529
530
531
532
533
534
535
536
537

538

539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
  }
  errno = savedErrno;
  return s;
}
#define fcntl lockTrace
#endif /* SQLITE_LOCK_TRACE */

#ifdef __linux__
/*
** This function is used as the main routine for a thread launched by
** testThreadLockingBehavior(). It tests whether the shared-lock obtained


** by the main thread in testThreadLockingBehavior() conflicts with a
** hypothetical write-lock obtained by this thread on the same file.
**
** The write-lock is not actually acquired, as this is not possible if 
** the file is open in read-only mode (see ticket #3472).
*/ 
static void *threadLockingTest(void *pArg){
  struct threadTestData *pData = (struct threadTestData*)pArg;
  pData->result = fcntl(pData->fd, F_GETLK, &pData->lock);
  return pArg;
}

/*
** This procedure attempts to determine whether or not threads
** can override each others locks then sets the 
** threadsOverrideEachOthersLocks variable appropriately.
*/
static void testThreadLockingBehavior(int fd_orig){
  int fd;
  int rc;
  struct threadTestData d;
  struct flock l;
  pthread_t t;

  fd = dup(fd_orig);
  if( fd<0 ) return;
  memset(&l, 0, sizeof(l));

  l.l_type = F_RDLCK;
  l.l_len = 1;
  l.l_start = 0;
  l.l_whence = SEEK_SET;
  rc = fcntl(fd_orig, F_SETLK, &l);
  if( rc!=0 ) return;
  memset(&d, 0, sizeof(d));
  d.fd = fd;
  d.lock = l;
  d.lock.l_type = F_WRLCK;
  pthread_create(&t, 0, threadLockingTest, &d);

  pthread_join(t, 0);

  close(fd);
  if( d.result!=0 ) return;
  threadsOverrideEachOthersLocks = (d.lock.l_type==F_UNLCK);
}
#else
/*
** On anything other than linux, assume threads override each others locks.
*/
static void testThreadLockingBehavior(int fd_orig){
  threadsOverrideEachOthersLocks = 1;
}
#endif /* __linux__ */

#endif /* SQLITE_THREADSAFE */

/*
** Release a lockInfo structure previously allocated by findLockInfo().
*/
static void releaseLockInfo(struct lockInfo *pLock){
  if( pLock ){
Added test/tkt3472.test.






































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# 2008 November 11
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
#     
# $Id: tkt3472.test,v 1.1 2008/11/11 18:34:35 danielk1977 Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

set ::correctvalue $threadsOverrideEachOthersLocks
puts "threadsOverrideEachOthersLocks = $::correctvalue"

do_test tkt3472-1.1 {
  db close
  set threadsOverrideEachOthersLocks -1
  sqlite3 db test.db
  set threadsOverrideEachOthersLocks
} $::correctvalue

do_test tkt3472-1.2 {
  db close
  set threadsOverrideEachOthersLocks -1
  sqlite3 db test.db -readonly 1
  set threadsOverrideEachOthersLocks
} $::correctvalue

finish_test