// File: /workspace/github_c_makefile_star2_O1/genometools[P]genometools/src/external/sqlite-3.33.0/sqlite3.c
// Function: sqlite3ConnectionUnlocked
SQLITE_PRIVATE void sqlite3ConnectionUnlocked(sqlite3 *db){
  void (*xUnlockNotify)(void **, int) = 0; /* Unlock-notify cb to invoke */
  int nArg = 0;                            /* Number of entries in aArg[] */
  sqlite3 **pp;                            /* Iterator variable */
  void **aArg;               /* Arguments to the unlock callback */
  void **aDyn = 0;           /* Dynamically allocated space for aArg[] */
  void *aStatic[16];         /* Starter space for aArg[].  No malloc required */

  aArg = aStatic;
  enterMutex();         /* Enter STATIC_MAIN mutex */

  /* This loop runs once for each entry in the blocked-connections list. */
  for(pp=&sqlite3BlockedList; *pp; /* no-op */ ){
    sqlite3 *p = *pp;

    /* Step 1. */
    if( p->pBlockingConnection==db ){
      p->pBlockingConnection = 0;
    }

    /* Step 2. */
    if( p->pUnlockConnection==db ){
      assert( p->xUnlockNotify );
      if( p->xUnlockNotify!=xUnlockNotify && nArg!=0 ){
        xUnlockNotify(aArg, nArg);
        nArg = 0;
      }

      sqlite3BeginBenignMalloc();
      assert( aArg==aDyn || (aDyn==0 && aArg==aStatic) );
      assert( nArg<=(int)ArraySize(aStatic) || aArg==aDyn );
      if( (!aDyn && nArg==(int)ArraySize(aStatic))
       || (aDyn && nArg==(int)(sqlite3MallocSize(aDyn)/sizeof(void*)))
      ){
        /* The aArg[] array needs to grow. */
        void **pNew = (void **)sqlite3Malloc(nArg*sizeof(void *)*2);
        if( pNew ){
          memcpy(pNew, aArg, nArg*sizeof(void *));
          sqlite3_free(aDyn);
          aDyn = aArg = pNew;
        }else{
          /* This occurs when the array of context pointers that need to
          ** be passed to the unlock-notify callback is larger than the
          ** aStatic[] array allocated on the stack and the attempt to
          ** allocate a larger array from the heap has failed.
          **
          ** This is a difficult situation to handle. Returning an error
          ** code to the caller is insufficient, as even if an error code
          ** is returned the transaction on connection db will still be
          ** closed and the unlock-notify callbacks on blocked connections
          ** will go unissued. This might cause the application to wait
          ** indefinitely for an unlock-notify callback that will never
          ** arrive.
          **
          ** Instead, invoke the unlock-notify callback with the context
          ** array already accumulated. We can then clear the array and
          ** begin accumulating any further context pointers without
          ** requiring any dynamic allocation. This is sub-optimal because
          ** it means that instead of one callback with a large array of
          ** context pointers the application will receive two or more
          ** callbacks with smaller arrays of context pointers, which will
          ** reduce the applications ability to prioritize multiple
          ** connections. But it is the best that can be done under the
          ** circumstances.
          */
          xUnlockNotify(aArg, nArg);
          nArg = 0;
        }
      }
      sqlite3EndBenignMalloc();

      aArg[nArg++] = p->pUnlockArg;
      xUnlockNotify = p->xUnlockNotify;
      p->pUnlockConnection = 0;
      p->xUnlockNotify = 0;
      p->pUnlockArg = 0;
    }

    /* Step 3. */
    if( p->pBlockingConnection==0 && p->pUnlockConnection==0 ){
      /* Remove connection p from the blocked connections list. */
      *pp = p->pNextBlocked;
      p->pNextBlocked = 0;
    }else{
      pp = &p->pNextBlocked;
    }
  }

  if( nArg!=0 ){
    xUnlockNotify(aArg, nArg);
  }
  sqlite3_free(aDyn);
  leaveMutex();         /* Leave STATIC_MAIN mutex */
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xa8, %rsp
movq 0x22f5a9(%rip), %r14    # 0x4c9e58
testq %r14, %r14
je 0x29aa1c
movq %rdi, %rbx
leaq 0x22f596(%rip), %rcx    # 0x4c9e58
leaq 0x20(%rsp), %r13
xorl %edx, %edx
xorl %ebp, %ebp
xorl %r12d, %r12d
movq %rdi, (%rsp)
cmpq %rbx, 0x2d8(%r14)
jne 0x29a8e6
movq $0x0, 0x2d8(%r14)
leaq 0x2e0(%r14), %r15
cmpq %rbx, 0x2e0(%r14)
jne 0x29a9dd
cmpq %rdx, 0x2f0(%r14)
movq %rcx, 0x18(%rsp)
movq %rdx, 0x10(%rsp)
je 0x29a91a
testl %ebp, %ebp
je 0x29a91a
movq %r13, %rdi
movl %ebp, %esi
callq *%rdx
xorl %ebp, %ebp
movq 0x22f527(%rip), %rax    # 0x4c9e48
testq %rax, %rax
je 0x29a928
callq *%rax
testq %r12, %r12
jne 0x29a932
cmpl $0x10, %ebp
je 0x29a947
testq %r12, %r12
je 0x29a9a0
movq %r12, %rdi
callq *0x22bd58(%rip)         # 0x4c6698
sarl $0x3, %eax
cmpl %eax, %ebp
jne 0x29a9a3
movq %r13, %rbx
movq %r12, 0x8(%rsp)
movslq %ebp, %r13
movq %r13, %rdi
shlq $0x4, %rdi
callq 0x27c381
testq %rax, %rax
je 0x29a987
movq %rax, %r12
shlq $0x3, %r13
movq %rax, %rdi
movq %rbx, %rsi
movq %r13, %rdx
callq 0x17660
movq 0x8(%rsp), %rdi
callq 0x27c490
movq %r12, %r13
jmp 0x29a99a
movq %rbx, %r13
movq %rbx, %rdi
movl %ebp, %esi
callq *0x10(%rsp)
xorl %ebp, %ebp
movq 0x8(%rsp), %r12
movq (%rsp), %rbx
jmp 0x29a9a3
xorl %r12d, %r12d
movq 0x22f4a6(%rip), %rax    # 0x4c9e50
testq %rax, %rax
je 0x29a9b1
callq *%rax
movq 0x2e8(%r14), %rax
movslq %ebp, %rcx
incl %ebp
movq %rax, (%r13,%rcx,8)
movq 0x2f0(%r14), %rdx
xorps %xmm0, %xmm0
movups %xmm0, (%r15)
movq $0x0, 0x10(%r15)
movq 0x18(%rsp), %rcx
cmpq $0x0, 0x2d8(%r14)
jne 0x29a9ed
cmpq $0x0, (%r15)
je 0x29aa05
addq $0x2f8, %r14            # imm = 0x2F8
movq %r14, %rcx
movq (%rcx), %r14
testq %r14, %r14
jne 0x29a8d2
jmp 0x29aa28
movq 0x2f8(%r14), %rax
movq %rax, (%rcx)
movq $0x0, 0x2f8(%r14)
jmp 0x29a9f7
xorl %r12d, %r12d
leaq 0x20(%rsp), %r13
xorl %ebp, %ebp
xorl %edx, %edx
testl %ebp, %ebp
je 0x29aa33
movq %r13, %rdi
movl %ebp, %esi
callq *%rdx
movq %r12, %rdi
callq 0x27c490
addq $0xa8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq