X-Recipient: archive-cygwin AT delorie DOT com DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:date:from:to:subject:message-id:reply-to :references:mime-version:content-type:in-reply-to; q=dns; s= default; b=PU/mUv4knrq2xOQPgUDaL+mqczPOcFkiW2KMjK11oJx2ggGjAbDms ZPTT4bNQvzNW9mvGYFWP3mSHFVMwBjLoY2/KVd9TQX6qmLa+WPpVNEBkArNYECFb RPr0lsc+ksJwOg6HkIsbX+X4TjM0qcWbQ2De/fZBF/+HeThBAOYq04= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:date:from:to:subject:message-id:reply-to :references:mime-version:content-type:in-reply-to; s=default; bh=KFO3SXi0rx+HMwWqkB6IP7vbtJQ=; b=TzE1wntLlShTpanp15Z363SrDCFH F5DbvlsMCkT/oDBzTG8ipnCy6W4GR7yVjot8umdI/kq8P5HVFcZUsX8QiZ95ZdxJ irqAeygdTaXoQtuRu4Tu2p5K9Lwc1dYfJxK312c1F4KC2Ts97+wcmFOVtSHumCHM dZiSvg4wWPbNfoo= Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-owner AT cygwin DOT com Mail-Followup-To: cygwin AT cygwin DOT com Delivered-To: mailing list cygwin AT cygwin DOT com X-Spam-SWARE-Status: No, score=-1.8 required=5.0 tests=AWL,BAYES_00,TW_FC autolearn=ham version=3.3.1 Date: Thu, 6 Jun 2013 19:22:18 +0200 From: Corinna Vinschen To: cygwin AT cygwin DOT com Subject: Re: [TEST] sqlite3-3.7.17-1 (Cygwin 1.7.19 locking feature) Message-ID: <20130606172218.GD13320@calimero.vinschen.de> Reply-To: cygwin AT cygwin DOT com Mail-Followup-To: cygwin AT cygwin DOT com References: <51ACF886 DOT 10301 AT etr-usa DOT com> <51AD3BB4 DOT 2010601 AT acm DOT org> <20130604084128 DOT GB19572 AT calimero DOT vinschen DOT de> <20130604093749 DOT GA32667 AT calimero DOT vinschen DOT de> <51AF9A32 DOT 2030706 AT etr-usa DOT com> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline In-Reply-To: <51AF9A32.2030706@etr-usa.com> User-Agent: Mutt/1.5.21 (2010-09-15) On Jun 5 14:06, Warren Young wrote: > On 6/4/2013 03:37, Corinna Vinschen wrote: > > > >It would be nice to have a simple testcase (plain C, only Cygwin > >POSIX calls, self-contained, yada yada) to see what sqlite expects in > >POSIX lock mode. > > SQLite locking is a hairball. It is spread over a range of about > 2.5 kLOC within the 140 kLOC sqlite3.c file, and those routines are > behind about three layers of indirection from the mainline SQLite > code. > > Mind, I'm not talking about the *callers* of this code here, just > the locking routines themselves. Add in all the callers and *their* > expectations and...well... > > I think we have to define the problem as "SQLite locking requires > what SQLite requires today." > > Luckily, while creating the -2 packages, I stumbled across a STC in > SQL that replicates the reported problem: > > $ ./sqlite3 foo.db 'create table fred(id integer, barney text)' > $ CYGWIN_SQLITE_LOCKING=posixmand ./sqlite3 foo.db \ > 'insert into fred(barney) values("wilma")' So, here's what happens. The below list contains the lock requests of sqlite up to the point where it fails. "r" is a read lock request, "w" a write lock request, "u" an unlock request. The next two values are the byte offset and byte length of the lock, the last is the status code after calling the Windows Lock/Unlock function: A. r 1073741824 1 STATUS_SUCCESS B. r 1073741826 510 STATUS_SUCCESS C. u 1073741824 1 STATUS_SUCCESS D. u 0 0 STATUS_RANGE_NOT_LOCKED ==> STATUS_SUCCESS E. r 1073741824 1 STATUS_SUCCESS F. r 1073741826 510 STATUS_SUCCESS G. u 1073741824 1 STATUS_SUCCESS H. w 1073741825 1 STATUS_SUCCESS I. w 1073741824 1 STATUS_SUCCESS J. w 1073741826 510 STATUS_LOCK_NOT_GRANTED K. r 1073741826 510 STATUS_SUCCESS L. u 1073741824 2 STATUS_RANGE_NOT_LOCKED ==> STATUS_SUCCESS M. u 0 0 STATUS_RANGE_NOT_LOCKED ==> STATUS_SUCCESS There are two problems: The lazy unlock request D tells the system to unlock all locks on the entire file. This works fine with POSIX locks, but it does not work with Windows locks. These require to unlock a lock exactly as it has been created. This means, after this unlock, the "r 1073741826 510" lock is still present. Since a failed unlock practically doesn't exist on POSIX, Cygwin converts STATUS_RANGE_NOT_LOCKED to STATUS_SUCCESS, so fcntl returns 0, success. Same for L and M, with L failing because the call tries to use a single unlock on a range holding two locks. The locks would have to be unlocked each by itself. Ultimately the write lock request J fails, because there are already the read locks B and F present. POSIX and BSD locks can simply replace another lock in the same spot if the existing lock is hold by the same process (POSIX) or file object (BSD). Windows locks add up, and require to unlock all locks in the same area before allowing another lock type to be placed. No atomic replacement of an existing read lock with a write lock or vice versa. In theory this scenario could be worked around in Cygwin by bookkeeping the present locks, plus a piece of code which unlocks all existing locks in the given range when a lock or unlock request is coming in. However, the really dismal fact is, that an unlock before a lock would never be atomic. If the F_SETLK request unlocks an existing lock and then another process gets a lock in the requested range, the first process ends up with a failed fcntl call and no lock at all. Corinna -- Corinna Vinschen Please, send mails regarding Cygwin to Cygwin Maintainer cygwin AT cygwin DOT com Red Hat -- Problem reports: http://cygwin.com/problems.html FAQ: http://cygwin.com/faq/ Documentation: http://cygwin.com/docs.html Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple