// Code generated by modernc.org/undup from the per-target sqlite_*.go files; DO NOT EDIT.

//go:build (linux && amd64) || (linux && arm) || (linux && arm64) || (linux && loong64) || (linux && ppc64le) || (linux && riscv64) || (linux && s390x)

package sqlite3

import (
	"unsafe"

	"modernc.org/libc"
)

// C documentation
//
//	/*
//	** This routine checks if there is a RESERVED lock held on the specified
//	** file by this or any other process. If such a lock is held, set *pResOut
//	** to a non-zero value otherwise *pResOut is set to zero.  The return value
//	** is set to SQLITE_OK unless an I/O error occurs during lock checking.
//	*/
func _unixCheckReservedLock(tls *libc.TLS, id uintptr, pResOut uintptr) (r int32) {
	bp := tls.Alloc(48)
	defer tls.Free(48)
	var pFile uintptr
	var rc, reserved int32
	var _ /* lock at bp+0 */ Tflock
	_, _, _ = pFile, rc, reserved
	rc = SQLITE_OK
	reserved = 0
	pFile = id
	Xsqlite3_mutex_enter(tls, (*TunixInodeInfo)(unsafe.Pointer((*TunixFile)(unsafe.Pointer(pFile)).FpInode)).FpLockMutex)
	/* Check if a thread in this process holds such a lock */
	if libc.Int32FromUint8((*TunixInodeInfo)(unsafe.Pointer((*TunixFile)(unsafe.Pointer(pFile)).FpInode)).FeFileLock) > int32(SHARED_LOCK) {
		reserved = int32(1)
	}
	/* Otherwise see if some other process holds it.
	 */
	if !(reserved != 0) && !((*TunixInodeInfo)(unsafe.Pointer((*TunixFile)(unsafe.Pointer(pFile)).FpInode)).FbProcessLock != 0) {
		(**(**Tflock)(__ccgo_up(bp))).Fl_whence = 0
		(**(**Tflock)(__ccgo_up(bp))).Fl_start = int64(_sqlite3PendingByte + libc.Int32FromInt32(1))
		(**(**Tflock)(__ccgo_up(bp))).Fl_len = int64(1)
		(**(**Tflock)(__ccgo_up(bp))).Fl_type = int16(F_WRLCK)
		if (*(*func(*libc.TLS, int32, int32, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[int32(7)].FpCurrent})))(tls, (*TunixFile)(unsafe.Pointer(pFile)).Fh, int32(F_GETLK), libc.VaList(bp+40, bp)) != 0 {
			rc = libc.Int32FromInt32(SQLITE_IOERR) | libc.Int32FromInt32(14)<<libc.Int32FromInt32(8)
			_storeLastErrno(tls, pFile, **(**int32)(__ccgo_up(libc.X__errno_location(tls))))
		} else {
			if int32((**(**Tflock)(__ccgo_up(bp))).Fl_type) != int32(F_UNLCK) {
				reserved = int32(1)
			}
		}
	}
	Xsqlite3_mutex_leave(tls, (*TunixInodeInfo)(unsafe.Pointer((*TunixFile)(unsafe.Pointer(pFile)).FpInode)).FpLockMutex)
	**(**int32)(__ccgo_up(pResOut)) = reserved
	return rc
}

/*
** Set a posix-advisory-lock.
**
** There are two versions of this routine.  If compiled with
** SQLITE_ENABLE_SETLK_TIMEOUT then the routine has an extra parameter
** which is a pointer to a unixFile.  If the unixFile->iBusyTimeout
** value is set, then it is the number of milliseconds to wait before
** failing the lock.  The iBusyTimeout value is always reset back to
** zero on each call.
**
** If SQLITE_ENABLE_SETLK_TIMEOUT is not defined, then do a non-blocking
** attempt to set the lock.
 */

// C documentation
//
//	/*
//	** Attempt to set a system-lock on the file pFile.  The lock is
//	** described by pLock.
//	**
//	** If the pFile was opened read/write from unix-excl, then the only lock
//	** ever obtained is an exclusive lock, and it is obtained exactly once
//	** the first time any lock is attempted.  All subsequent system locking
//	** operations become no-ops.  Locking operations still happen internally,
//	** in order to coordinate access between separate database connections
//	** within this process, but all of that is handled in memory and the
//	** operating system does not participate.
//	**
//	** This function is a pass-through to fcntl(F_SETLK) if pFile is using
//	** any VFS other than "unix-excl" or if pFile is opened on "unix-excl"
//	** and is read-only.
//	**
//	** Zero is returned if the call completes successfully, or -1 if a call
//	** to fcntl() fails. In this case, errno is set appropriately (by fcntl()).
//	*/
func _unixFileLock(tls *libc.TLS, pFile uintptr, pLock uintptr) (r int32) {
	bp := tls.Alloc(48)
	defer tls.Free(48)
	var pInode uintptr
	var rc int32
	var _ /* lock at bp+0 */ Tflock
	_, _ = pInode, rc
	pInode = (*TunixFile)(unsafe.Pointer(pFile)).FpInode
	if libc.Int32FromUint16((*TunixFile)(unsafe.Pointer(pFile)).FctrlFlags)&(libc.Int32FromInt32(UNIXFILE_EXCL)|libc.Int32FromInt32(UNIXFILE_RDONLY)) == int32(UNIXFILE_EXCL) {
		if libc.Int32FromUint8((*TunixInodeInfo)(unsafe.Pointer(pInode)).FbProcessLock) == 0 {
			/* assert( pInode->nLock==0 ); <-- Not true if unix-excl READONLY used */
			(**(**Tflock)(__ccgo_up(bp))).Fl_whence = 0
			(**(**Tflock)(__ccgo_up(bp))).Fl_start = int64(_sqlite3PendingByte + libc.Int32FromInt32(2))
			(**(**Tflock)(__ccgo_up(bp))).Fl_len = int64(SHARED_SIZE)
			(**(**Tflock)(__ccgo_up(bp))).Fl_type = int16(F_WRLCK)
			rc = (*(*func(*libc.TLS, int32, int32, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[int32(7)].FpCurrent})))(tls, (*TunixFile)(unsafe.Pointer(pFile)).Fh, int32(F_SETLK), libc.VaList(bp+40, bp))
			if rc < 0 {
				return rc
			}
			(*TunixInodeInfo)(unsafe.Pointer(pInode)).FbProcessLock = uint8(1)
			(*TunixInodeInfo)(unsafe.Pointer(pInode)).FnLock = (*TunixInodeInfo)(unsafe.Pointer(pInode)).FnLock + 1
		} else {
			rc = 0
		}
	} else {
		rc = (*(*func(*libc.TLS, int32, int32, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[int32(7)].FpCurrent})))(tls, (*TunixFile)(unsafe.Pointer(pFile)).Fh, int32(F_SETLK), libc.VaList(bp+40, pLock))
	}
	return rc
}

// C documentation
//
//	/*
//	** Apply posix advisory locks for all bytes from ofst through ofst+n-1.
//	**
//	** Locks block if the mask is exactly UNIX_SHM_C and are non-blocking
//	** otherwise.
//	*/
func _unixShmSystemLock(tls *libc.TLS, pFile uintptr, lockType int32, ofst int32, n int32) (r int32) {
	bp := tls.Alloc(48)
	defer tls.Free(48)
	var pShmNode uintptr
	var rc, res int32
	var _ /* f at bp+0 */ Tflock
	_, _, _ = pShmNode, rc, res /* The posix advisory locking structure */
	rc = SQLITE_OK              /* Result code form fcntl() */
	pShmNode = (*TunixInodeInfo)(unsafe.Pointer((*TunixFile)(unsafe.Pointer(pFile)).FpInode)).FpShmNode
	/* Assert that the parameters are within expected range and that the
	 ** correct mutex or mutexes are held. */
	if ofst == (libc.Int32FromInt32(22)+libc.Int32FromInt32(SQLITE_SHM_NLOCK))*libc.Int32FromInt32(4)+libc.Int32FromInt32(SQLITE_SHM_NLOCK) {
	} else {
	}
	/* Shared locks never span more than one byte */
	/* Locks are within range */
	if (*TunixShmNode)(unsafe.Pointer(pShmNode)).FhShm >= 0 {
		/* Initialize the locking parameters */
		(**(**Tflock)(__ccgo_up(bp))).Fl_type = int16(lockType)
		(**(**Tflock)(__ccgo_up(bp))).Fl_whence = 0
		(**(**Tflock)(__ccgo_up(bp))).Fl_start = int64(ofst)
		(**(**Tflock)(__ccgo_up(bp))).Fl_len = int64(n)
		res = (*(*func(*libc.TLS, int32, int32, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[int32(7)].FpCurrent})))(tls, (*TunixShmNode)(unsafe.Pointer(pShmNode)).FhShm, int32(F_SETLK), libc.VaList(bp+40, bp))
		if res == -int32(1) {
			rc = int32(SQLITE_BUSY)
		}
	}
	/* Do debug tracing */
	return rc
}
