System.Data.SQLite
Check-in [74a33d10da]
Not logged in

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

Overview
Comment:Modify the native interop assembly to help prevent possible thread race conditions between sqlite3_close_interop and sqlite3_finalize_interop.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 74a33d10da8b97429d4d4c0e285d4dd3e757c031
User & Date: mistachkin 2012-06-02 00:14:36
Context
2012-06-02
00:54
Prevent possible race conditions involving the managed backup API methods. check-in: fc724d683a user: mistachkin tags: trunk
00:14
Modify the native interop assembly to help prevent possible thread race conditions between sqlite3_close_interop and sqlite3_finalize_interop. check-in: 74a33d10da user: mistachkin tags: trunk
2012-05-27
21:54
Doc and packaging updates for release 1.0.81.0. check-in: 84c0e6e786 user: mistachkin tags: trunk, release, release-1.0.81.0
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to SQLite.Interop/src/win/interop.c.

60
61
62
63
64
65
66
67
68








69
70
71
72
73
74
75
..
98
99
100
101
102
103
104

105
106
107
108
109
110
111
...
232
233
234
235
236
237
238
239
240
241
242
243

244
245

246

247


248
249
250
251
252

253





254
255
256
257
258
259
260
*/
SQLITE_API int WINAPI sqlite3_close_interop(sqlite3 *db)
{
  int ret;
  
  ret = sqlite3_close(db);

  if (ret == SQLITE_BUSY && db->pVdbe)
  {








    while (db->pVdbe)
    {
      // Make a copy of the first prepared statement
      Vdbe *p = (Vdbe *)sqlite3DbMallocZero_interop(db, sizeof(Vdbe));
      Vdbe *po = db->pVdbe;

      if (!p) 
................................................................................
      }
      else
      {
        ZeroMemory(po, sizeof(Vdbe));
        po->magic = VDBE_MAGIC_DEAD;
      }
    }

    ret = sqlite3_close(db);
  }

  return ret;
}

SQLITE_API int WINAPI sqlite3_open_interop(const char*filename, int flags, sqlite3 **ppdb)
................................................................................
  *plen = (pval != 0) ? wcslen((wchar_t *)pval) * sizeof(wchar_t): 0;
  return pval;
}

SQLITE_API int WINAPI sqlite3_finalize_interop(sqlite3_stmt *stmt)
{
  Vdbe *p;
  sqlite3 *db;
  int ret;

  p = (Vdbe *)stmt;
  if (p && p->magic == VDBE_MAGIC_DEAD)

  {
    db = p->db;

    if (db == NULL)

    {


      sqlite3DbFree_interop(db, p);
      ret = SQLITE_OK;
    }
  }
  else

    ret = sqlite3_finalize(stmt);






  return ret;
}

SQLITE_API int WINAPI sqlite3_reset_interop(sqlite3_stmt *stmt)
{
  int ret;







|

>
>
>
>
>
>
>
>







 







>







 







<
|


<
>

|
>
|
>
|
>
>

<

<
|
>
|
>
>
>
>
>







60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
...
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
...
241
242
243
244
245
246
247

248
249
250

251
252
253
254
255
256
257
258
259
260

261

262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
*/
SQLITE_API int WINAPI sqlite3_close_interop(sqlite3 *db)
{
  int ret;
  
  ret = sqlite3_close(db);

  if (ret == SQLITE_BUSY)
  {
    sqlite3_mutex_enter(db->mutex);

    if (!db->pVdbe)
    {
      sqlite3_mutex_leave(db->mutex);
      return ret;
    }

    while (db->pVdbe)
    {
      // Make a copy of the first prepared statement
      Vdbe *p = (Vdbe *)sqlite3DbMallocZero_interop(db, sizeof(Vdbe));
      Vdbe *po = db->pVdbe;

      if (!p) 
................................................................................
      }
      else
      {
        ZeroMemory(po, sizeof(Vdbe));
        po->magic = VDBE_MAGIC_DEAD;
      }
    }
    sqlite3_mutex_leave(db->mutex);
    ret = sqlite3_close(db);
  }

  return ret;
}

SQLITE_API int WINAPI sqlite3_open_interop(const char*filename, int flags, sqlite3 **ppdb)
................................................................................
  *plen = (pval != 0) ? wcslen((wchar_t *)pval) * sizeof(wchar_t): 0;
  return pval;
}

SQLITE_API int WINAPI sqlite3_finalize_interop(sqlite3_stmt *stmt)
{
  Vdbe *p;

  int ret = SQLITE_OK;

  p = (Vdbe *)stmt;

  if (p)
  {
    sqlite3 *db = p->db;

    if (db != NULL)
      sqlite3_mutex_enter(db->mutex);

    if ((p->magic == VDBE_MAGIC_DEAD) && (db == NULL))
    {
      sqlite3DbFree_interop(db, p);

    }

    else
    {
      ret = sqlite3_finalize(stmt);
    }

    if (db != NULL)
      sqlite3_mutex_leave(db->mutex);
  }

  return ret;
}

SQLITE_API int WINAPI sqlite3_reset_interop(sqlite3_stmt *stmt)
{
  int ret;