/ Check-in [aa61b244]
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

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

Overview
Comment:Initial attempt of the new OS/2 mutex implementation. (Compiles and an attempt to create a new table does not crash in mutex_os2 any more.) (CVS 4442)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: aa61b244252399cce3b9c1ece9c6816ae9cb6717
User & Date: pweilbacher 2007-09-20 21:40:23
Context
2007-09-21
04:27
Fix a typo in comments. Ticket #2660. (CVS 4443) check-in: 02c8d60b user: danielk1977 tags: trunk
2007-09-20
21:40
Initial attempt of the new OS/2 mutex implementation. (Compiles and an attempt to create a new table does not crash in mutex_os2 any more.) (CVS 4442) check-in: aa61b244 user: pweilbacher tags: trunk
14:39
Replace "i64" with "sqlite3_int64" in the w32 VFS. (CVS 4441) check-in: 138d3fcc user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/mutex_os2.c.

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
36


37
38
39
40
41
42


































43
44
45


46

47
48
49
50

51


52
53


54
55
56
57
























58
59
60


61
62
63
64
65
66

67
68
69

70
71
72
73
74


75
76
77
78
79
80
81
..
83
84
85
86
87
88
89



90
91
92




93
94




95
96
97




98





99
100
101
102
103
104
105
106
107



108
109
110



111

112
113
114
115
116
117
118










119
120
121










122
123
124
**    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.
**
*************************************************************************
** This file contains the C functions that implement mutexes for OS/2
**
** $Id: mutex_os2.c,v 1.1 2007/08/28 16:34:43 drh Exp $
*/
#include "sqliteInt.h"


/*
** The code in this file is only used if SQLITE_MUTEX_OS2 is defined.
** See the mutex.h file for details.
*/
#ifdef SQLITE_MUTEX_OS2

/**** FIX ME:
***** This is currently a no-op implementation suitable for use
***** in single-threaded applications only.  Somebody please replace
***** this with a real mutex implementation for OS/2.
****/

/*
** The mutex object

*/
struct sqlite3_mutex {


  int id;     /* The mutex type */
  int cnt;    /* Number of entries without a matching leave */


};

/*
** The sqlite3_mutex_alloc() routine allocates a new
** mutex and returns a pointer to it.  If it returns NULL
** that means that a mutex could not be allocated. 


































*/
sqlite3_mutex *sqlite3_mutex_alloc(int id){
  static sqlite3_mutex aStatic[4];


  sqlite3_mutex *pNew = 0;

  switch( id ){
    case SQLITE_MUTEX_FAST:
    case SQLITE_MUTEX_RECURSIVE: {
      pNew = sqlite3_malloc(sizeof(*pNew));

      if( pNew ){


        pNew->id = id;
        pNew->cnt = 0;


      }
      break;
    }
    default: {
























      assert( id-2 >= 0 );
      assert( id-2 < sizeof(aStatic)/sizeof(aStatic[0]) );
      pNew = &aStatic[id-2];


      pNew->id = id;
      break;
    }
  }
  return pNew;
}


/*
** This routine deallocates a previously allocated mutex.

*/
void sqlite3_mutex_free(sqlite3_mutex *p){
  assert( p );
  assert( p->cnt==0 );
  assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE );


  sqlite3_free(p);
}

/*
** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt
** to enter a mutex.  If another thread is already within the mutex,
** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return
................................................................................
** upon successful entry.  Mutexes created using SQLITE_MUTEX_RECURSIVE can
** be entered multiple times by the same thread.  In such cases the,
** mutex must be exited an equal number of times before another thread
** can enter.  If the same thread tries to enter any other kind of mutex
** more than once, the behavior is undefined.
*/
void sqlite3_mutex_enter(sqlite3_mutex *p){



  assert( p );
  assert( p->id==SQLITE_MUTEX_RECURSIVE || sqlite3_mutex_notheld(p) );
  p->cnt++;




}
int sqlite3_mutex_try(sqlite3_mutex *p){




  assert( p );
  assert( p->id==SQLITE_MUTEX_RECURSIVE || sqlite3_mutex_notheld(p) );
  p->cnt++;




  return SQLITE_OK;





}

/*
** The sqlite3_mutex_leave() routine exits a mutex that was
** previously entered by the same thread.  The behavior
** is undefined if the mutex is not currently entered or
** is not currently allocated.  SQLite will never do either.
*/
void sqlite3_mutex_leave(sqlite3_mutex *p){



  assert( p );
  assert( sqlite3_mutex_held(p) );
  p->cnt--;



  assert( p->id==SQLITE_MUTEX_RECURSIVE || sqlite3_mutex_notheld(p) );

}

/*
** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are
** intended for use inside assert() statements.
*/
int sqlite3_mutex_held(sqlite3_mutex *p){










  return p==0 || p->cnt>0;
}
int sqlite3_mutex_notheld(sqlite3_mutex *p){










  return p==0 || p->cnt==0;
}
#endif /* SQLITE_MUTEX_OS2 */







|


<







|
|
|
|
<



>


>
>
|
<
>
>






>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

|
<
>
>
|
>
|


<
>
|
>
>
|
<
>
>




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



|

>



>



|

>
>







 







>
>
>


<
>
>
>
>


>
>
>
>


<
>
>
>
>
|
>
>
>
>
>









>
>
>
|
<
<
>
>
>
|
>







>
>
>
>
>
>
>
>
>
>
|


>
>
>
>
>
>
>
>
>
>
|


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
36

37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80

81
82
83
84
85
86
87

88
89
90
91
92

93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123


124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
...
152
153
154
155
156
157
158
159
160
161
162
163

164
165
166
167
168
169
170
171
172
173
174
175

176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198


199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
**    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.
**
*************************************************************************
** This file contains the C functions that implement mutexes for OS/2
**
** $Id: mutex_os2.c,v 1.2 2007/09/20 21:40:23 pweilbacher Exp $
*/
#include "sqliteInt.h"


/*
** The code in this file is only used if SQLITE_MUTEX_OS2 is defined.
** See the mutex.h file for details.
*/
#ifdef SQLITE_MUTEX_OS2

/********************** OS/2 Mutex Implementation **********************
**
** This implementation of mutexes is built using the OS/2 API.
*/


/*
** The mutex object
** Each recursive mutex is an instance of the following structure.
*/
struct sqlite3_mutex {
  PSZ  mutexName;   /* Mutex name controlling the lock */
  HMTX mutex;       /* Mutex controlling the lock */
  int  id;          /* Mutex type */

  int  nRef;        /* Number of references */
  TID  owner;       /* Thread holding this mutex */
};

/*
** The sqlite3_mutex_alloc() routine allocates a new
** mutex and returns a pointer to it.  If it returns NULL
** that means that a mutex could not be allocated. 
** SQLite will unwind its stack and return an error.  The argument
** to sqlite3_mutex_alloc() is one of these integer constants:
**
** <ul>
** <li>  SQLITE_MUTEX_FAST               0
** <li>  SQLITE_MUTEX_RECURSIVE          1
** <li>  SQLITE_MUTEX_STATIC_MASTER      2
** <li>  SQLITE_MUTEX_STATIC_MEM         3
** <li>  SQLITE_MUTEX_STATIC_PRNG        4
** </ul>
**
** The first two constants cause sqlite3_mutex_alloc() to create
** a new mutex.  The new mutex is recursive when SQLITE_MUTEX_RECURSIVE
** is used but not necessarily so when SQLITE_MUTEX_FAST is used.
** The mutex implementation does not need to make a distinction
** between SQLITE_MUTEX_RECURSIVE and SQLITE_MUTEX_FAST if it does
** not want to.  But SQLite will only request a recursive mutex in
** cases where it really needs one.  If a faster non-recursive mutex
** implementation is available on the host platform, the mutex subsystem
** might return such a mutex in response to SQLITE_MUTEX_FAST.
**
** The other allowed parameters to sqlite3_mutex_alloc() each return
** a pointer to a static preexisting mutex.  Three static mutexes are
** used by the current version of SQLite.  Future versions of SQLite
** may add additional static mutexes.  Static mutexes are for internal
** use by SQLite only.  Applications that use SQLite mutexes should
** use only the dynamic mutexes returned by SQLITE_MUTEX_FAST or
** SQLITE_MUTEX_RECURSIVE.
**
** Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST
** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc()
** returns a different mutex on every call.  But for the static
** mutex types, the same mutex is returned on every call that has
** the same type number.
*/
sqlite3_mutex *sqlite3_mutex_alloc(int iType){

#define MUTEX_NAME "\\SEM32\\SQLITE\\MUTEX"
#define MUTEX_NAME_LEN 20 /* name length + null byte */
  sqlite3_mutex *p;

  switch( iType ){
    case SQLITE_MUTEX_FAST:
    case SQLITE_MUTEX_RECURSIVE: {

      p = sqlite3MallocZero( sizeof(*p) );
      if( p ){
        p->mutexName = (PSZ)malloc(MUTEX_NAME_LEN);
        sqlite3_snprintf(MUTEX_NAME_LEN, p->mutexName, "%s", MUTEX_NAME);
        p->id = iType;

        DosCreateMutexSem(p->mutexName, &p->mutex, 0, FALSE);
        DosOpenMutexSem(p->mutexName, &p->mutex);
      }
      break;
    }
    default: {
      static sqlite3_mutex staticMutexes[5];
      static int isInit = 0;
      while( !isInit ) {
        static long lock = 0;
        DosEnterCritSec();
        lock++;
        if( lock == 1 ) {
          DosExitCritSec();
          int i;
          for(i = 0; i < sizeof(staticMutexes)/sizeof(staticMutexes[0]); i++) {
            staticMutexes[i].mutexName = (PSZ)malloc(MUTEX_NAME_LEN + 1);
            sqlite3_snprintf(MUTEX_NAME_LEN + 1,
                             staticMutexes[i].mutexName, "%s%1d", MUTEX_NAME, i);
            DosCreateMutexSem(staticMutexes[i].mutexName,
                              &staticMutexes[i].mutex, 0, FALSE);
            DosOpenMutexSem(staticMutexes[i].mutexName,
                            &staticMutexes[i].mutex);
          }
          isInit = 1;
        } else {
          DosExitCritSec();
          DosSleep(1);
        }
      }
      assert( iType-2 >= 0 );


      assert( iType-2 < sizeof(staticMutexes)/sizeof(staticMutexes[0]) );
      p = &staticMutexes[iType-2];
      p->id = iType;
      break;
    }
  }
  return p;
}


/*
** This routine deallocates a previously allocated mutex.
** SQLite is careful to deallocate every mutex that it allocates.
*/
void sqlite3_mutex_free(sqlite3_mutex *p){
  assert( p );
  assert( p->nRef==0 );
  assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE );
  DosCloseMutexSem(p->mutex);
  free(p->mutexName);
  sqlite3_free(p);
}

/*
** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt
** to enter a mutex.  If another thread is already within the mutex,
** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return
................................................................................
** upon successful entry.  Mutexes created using SQLITE_MUTEX_RECURSIVE can
** be entered multiple times by the same thread.  In such cases the,
** mutex must be exited an equal number of times before another thread
** can enter.  If the same thread tries to enter any other kind of mutex
** more than once, the behavior is undefined.
*/
void sqlite3_mutex_enter(sqlite3_mutex *p){
  TID tid;
  PID holder1;
  ULONG holder2;
  assert( p );
  assert( p->id==SQLITE_MUTEX_RECURSIVE || sqlite3_mutex_notheld(p) );

  DosRequestMutexSem(p->mutex, SEM_INDEFINITE_WAIT);
  DosQueryMutexSem(p->mutex, &holder1, &tid, &holder2);
  p->owner = tid;
  p->nRef++;
}
int sqlite3_mutex_try(sqlite3_mutex *p){
  int rc;
  TID tid;
  PID holder1;
  ULONG holder2;
  assert( p );
  assert( p->id==SQLITE_MUTEX_RECURSIVE || sqlite3_mutex_notheld(p) );

  if( DosRequestMutexSem(p->mutex, SEM_IMMEDIATE_RETURN) == NO_ERROR) {
    DosQueryMutexSem(p->mutex, &holder1, &tid, &holder2);
    p->owner = tid;
    p->nRef++;
    rc = SQLITE_OK;
  } else {
    rc = SQLITE_BUSY;
  }

  return rc;
}

/*
** The sqlite3_mutex_leave() routine exits a mutex that was
** previously entered by the same thread.  The behavior
** is undefined if the mutex is not currently entered or
** is not currently allocated.  SQLite will never do either.
*/
void sqlite3_mutex_leave(sqlite3_mutex *p){
  TID tid;
  PID holder1;
  ULONG holder2;
  assert( p->nRef>0 );


  DosQueryMutexSem(p->mutex, &holder1, &tid, &holder2);
  assert( p->owner==tid );
  p->nRef--;
  assert( p->nRef==0 || p->id==SQLITE_MUTEX_RECURSIVE );
  DosReleaseMutexSem(p->mutex);
}

/*
** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are
** intended for use inside assert() statements.
*/
int sqlite3_mutex_held(sqlite3_mutex *p){
  TID tid;
  PID pid;
  ULONG ulCount;
  PTIB ptib;
  if( p!=0 ) {
    DosQueryMutexSem(p->mutex, &pid, &tid, &ulCount);
  } else {
    DosGetInfoBlocks(&ptib, NULL);
    tid = ptib->tib_ptib2->tib2_ultid;
  }
  return p==0 || (p->nRef!=0 && p->owner==tid);
}
int sqlite3_mutex_notheld(sqlite3_mutex *p){
  TID tid;
  PID pid;
  ULONG ulCount;
  PTIB ptib;
  if( p!= 0 ) {
    DosQueryMutexSem(p->mutex, &pid, &tid, &ulCount);
  } else {
    DosGetInfoBlocks(&ptib, NULL);
    tid = ptib->tib_ptib2->tib2_ultid;
  }
  return p==0 || p->nRef==0 || p->owner!=tid;
}
#endif /* SQLITE_MUTEX_OS2 */