~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to mysys/thr_lock.c

  • Committer: Brian Aker
  • Date: 2008-07-02 21:31:48 UTC
  • mfrom: (28.1.41 libtool-patch)
  • Revision ID: brian@tangent.org-20080702213148-pc4f4hjt5c9qvp00
Merge from Monty Taylor.

Show diffs side-by-side

added added

removed removed

Lines of Context:
76
76
 
77
77
#include "mysys_priv.h"
78
78
 
79
 
#ifdef THREAD
80
79
#include "thr_lock.h"
81
80
#include <m_string.h>
82
81
#include <errno.h>
1180
1179
#ifndef DBUG_OFF
1181
1180
  enum thr_lock_type old_lock_type= in_data->type;
1182
1181
#endif
1183
 
#ifdef TO_BE_REMOVED
1184
 
  THR_LOCK_DATA *data, *next;
1185
 
  bool start_writers= FALSE;
1186
 
  bool start_readers= FALSE;
1187
 
#endif
1188
1182
  DBUG_ENTER("thr_downgrade_write_only_lock");
1189
1183
 
1190
1184
  pthread_mutex_lock(&lock->mutex);
1193
1187
  in_data->type= new_lock_type;
1194
1188
  check_locks(lock,"after downgrading lock",0);
1195
1189
 
1196
 
#if TO_BE_REMOVED
1197
 
  switch (old_lock_type)
1198
 
  {
1199
 
    case TL_WRITE_ONLY:
1200
 
    case TL_WRITE:
1201
 
    case TL_WRITE_LOW_PRIORITY:
1202
 
    /*
1203
 
      Previous lock was exclusive we are now ready to start up most waiting
1204
 
      threads.
1205
 
    */
1206
 
      switch (new_lock_type)
1207
 
      {
1208
 
        case TL_WRITE_ALLOW_READ:
1209
 
        /* Still cannot start WRITE operations. Can only start readers.  */
1210
 
          start_readers= TRUE;
1211
 
          break;
1212
 
        case TL_WRITE:
1213
 
        case TL_WRITE_LOW_PRIORITY:
1214
 
        /*
1215
 
           Still cannot start anything, but new requests are no longer
1216
 
           aborted.
1217
 
        */
1218
 
          break;
1219
 
        case TL_WRITE_ALLOW_WRITE:
1220
 
        /*
1221
 
          We can start both writers and readers.
1222
 
        */
1223
 
          start_writers= TRUE;
1224
 
          start_readers= TRUE;
1225
 
          break;
1226
 
        case TL_WRITE_CONCURRENT_INSERT:
1227
 
        case TL_WRITE_DELAYED:
1228
 
        /*
1229
 
          This routine is not designed for those. Lock will be downgraded
1230
 
          but no start of waiters will occur. This is not the optimal but
1231
 
          should be a correct behaviour.
1232
 
        */
1233
 
          break;
1234
 
        default:
1235
 
          DBUG_ASSERT(0);
1236
 
      }
1237
 
      break;
1238
 
    case TL_WRITE_DELAYED:
1239
 
    case TL_WRITE_CONCURRENT_INSERT:
1240
 
    /*
1241
 
      This routine is not designed for those. Lock will be downgraded
1242
 
      but no start of waiters will occur. This is not the optimal but
1243
 
      should be a correct behaviour.
1244
 
    */
1245
 
      break;
1246
 
    case TL_WRITE_ALLOW_READ:
1247
 
      DBUG_ASSERT(new_lock_type == TL_WRITE_ALLOW_WRITE);
1248
 
      /*
1249
 
        Previously writers were not allowed to start, now it is ok to
1250
 
        start them again. Readers are already allowed so no reason to
1251
 
        handle them.
1252
 
      */
1253
 
      start_writers= TRUE;
1254
 
      break;
1255
 
    default:
1256
 
      DBUG_ASSERT(0);
1257
 
      break;
1258
 
  }
1259
 
  if (start_writers)
1260
 
  {
1261
 
    /*
1262
 
      At this time the only active writer can be ourselves. Thus we need
1263
 
      not worry about that there are other concurrent write operations
1264
 
      active on the table. Thus we only need to worry about starting
1265
 
      waiting operations.
1266
 
      We also only come here with TL_WRITE_ALLOW_WRITE as the new
1267
 
      lock type, thus we can start other writers also of the same type.
1268
 
      If we find a lock at exclusive level >= TL_WRITE_LOW_PRIORITY we
1269
 
      don't start any more operations that would be mean those operations
1270
 
      will have to wait for things started afterwards.
1271
 
    */
1272
 
    DBUG_ASSERT(new_lock_type == TL_WRITE_ALLOW_WRITE);
1273
 
    for (data=lock->write_wait.data; data ; data= next)
1274
 
    {
1275
 
      /*
1276
 
        All WRITE requests compatible with new lock type are also
1277
 
        started
1278
 
      */
1279
 
      next= data->next;
1280
 
      if (start_writers && data->type == new_lock_type)
1281
 
      {
1282
 
        pthread_cond_t *cond= data->cond;
1283
 
        /*
1284
 
          It is ok to start this waiter.
1285
 
          Move from being first in wait queue to be last in write queue.
1286
 
        */
1287
 
        if (((*data->prev)= data->next))
1288
 
          data->next->prev= data->prev;
1289
 
        else
1290
 
          lock->write_wait.last= data->prev;
1291
 
        data->prev= lock->write.last;
1292
 
        lock->write.last= &data->next;
1293
 
        data->next= 0;
1294
 
        check_locks(lock, "Started write lock after downgrade",0);
1295
 
        data->cond= 0;
1296
 
        pthread_cond_signal(cond);
1297
 
      }
1298
 
      else
1299
 
      {
1300
 
        /*
1301
 
          We found an incompatible lock, we won't start any more write
1302
 
          requests to avoid letting writers pass other writers in the
1303
 
          queue.
1304
 
        */
1305
 
        start_writers= FALSE;
1306
 
        if (data->type >= TL_WRITE_LOW_PRIORITY)
1307
 
        {
1308
 
          /*
1309
 
            We have an exclusive writer in the queue so we won't start
1310
 
            readers either.
1311
 
          */
1312
 
          start_readers= FALSE;
1313
 
        }
1314
 
      }
1315
 
    }
1316
 
  }
1317
 
  if (start_readers)
1318
 
  {
1319
 
    DBUG_ASSERT(new_lock_type == TL_WRITE_ALLOW_WRITE ||
1320
 
                new_lock_type == TL_WRITE_ALLOW_READ);
1321
 
    /*
1322
 
      When we come here we know that the write locks are
1323
 
      TL_WRITE_ALLOW_WRITE or TL_WRITE_ALLOW_READ. This means that reads
1324
 
      are ok
1325
 
    */
1326
 
    for (data=lock->read_wait.data; data ; data=next)
1327
 
    {
1328
 
      next= data->next;
1329
 
      /*
1330
 
        All reads are ok to start now except TL_READ_NO_INSERT when
1331
 
        write lock is TL_WRITE_ALLOW_READ.
1332
 
      */
1333
 
      if (new_lock_type != TL_WRITE_ALLOW_READ ||
1334
 
          data->type != TL_READ_NO_INSERT)
1335
 
      {
1336
 
        pthread_cond_t *cond= data->cond;
1337
 
        if (((*data->prev)= data->next))
1338
 
          data->next->prev= data->prev;
1339
 
        else
1340
 
          lock->read_wait.last= data->prev;
1341
 
        data->prev= lock->read.last;
1342
 
        lock->read.last= &data->next;
1343
 
        data->next= 0;
1344
 
 
1345
 
        if (data->type == TL_READ_NO_INSERT)
1346
 
          lock->read_no_write_count++;
1347
 
        check_locks(lock, "Started read lock after downgrade",0);
1348
 
        data->cond= 0;
1349
 
        pthread_cond_signal(cond);
1350
 
      }
1351
 
    }
1352
 
  }
1353
 
  check_locks(lock,"after starting waiters after downgrading lock",0);
1354
 
#endif
1355
1190
  pthread_mutex_unlock(&lock->mutex);
1356
1191
  DBUG_VOID_RETURN;
1357
1192
}
1502
1337
  pthread_mutex_unlock(&THR_LOCK_lock);
1503
1338
}
1504
1339
 
1505
 
#endif /* THREAD */
1506
 
 
1507
1340
/*****************************************************************************
1508
1341
** Test of thread locks
1509
1342
****************************************************************************/
1510
1343
 
1511
1344
#ifdef MAIN
1512
1345
 
1513
 
#ifdef THREAD
1514
 
 
1515
1346
struct st_test {
1516
1347
  uint lock_nr;
1517
1348
  enum thr_lock_type lock_type;
1741
1572
  return 0;
1742
1573
}
1743
1574
 
1744
 
#else /* THREAD */
1745
 
 
1746
 
int main(int argc __attribute__((unused)),char **argv __attribute__((unused)))
1747
 
{
1748
 
  printf("thr_lock disabled because we are not using threads\n");
1749
 
  exit(1);
1750
 
}
1751
 
 
1752
 
#endif /* THREAD */
1753
1575
#endif /* MAIN */