~ubuntu-branches/debian/jessie/389-ds-base/jessie

« back to all changes in this revision

Viewing changes to ldap/servers/slapd/back-ldbm/cache.c

  • Committer: Package Import Robot
  • Author(s): Timo Aaltonen
  • Date: 2014-09-01 13:32:59 UTC
  • mfrom: (0.2.4)
  • Revision ID: package-import@ubuntu.com-20140901133259-kfw30bd5t1g19qaq
Tags: 1.3.2.23-1
* New bugfix release.
* watch: Update the url.
* control: Update Vcs-Browser url to use cgit.

Show diffs side-by-side

added added

removed removed

Lines of Context:
544
544
    cache->c_lruhead = cache->c_lrutail = NULL;
545
545
    cache_make_hashes(cache, type);
546
546
 
547
 
    if (((cache->c_mutex = PR_NewLock()) == NULL) ||
548
 
       ((cache->c_emutexalloc_mutex = PR_NewLock()) == NULL)) {
549
 
       LDAPDebug(LDAP_DEBUG_ANY, "ldbm: cache_init: PR_NewLock failed\n",
550
 
                0, 0, 0);
 
547
    if (((cache->c_mutex = PR_NewMonitor()) == NULL) ||
 
548
        ((cache->c_emutexalloc_mutex = PR_NewLock()) == NULL)) {
 
549
       LDAPDebug0Args(LDAP_DEBUG_ANY, "ldbm: cache_init: PR_NewMonitor failed\n");
551
550
       return 0;
552
551
    }
553
552
    LDAPDebug(LDAP_DEBUG_TRACE, "<= cache_init\n", 0, 0, 0);
634
633
 
635
634
void cache_clear(struct cache *cache, int type)
636
635
{
637
 
    PR_Lock(cache->c_mutex);
 
636
    cache_lock(cache);
638
637
    if (CACHE_TYPE_ENTRY == type) {
639
638
        entrycache_clear_int(cache);
640
639
    } else if (CACHE_TYPE_DN == type) {
641
640
        dncache_clear_int(cache);
642
641
    }
643
 
    PR_Unlock(cache->c_mutex);
 
642
    cache_unlock(cache);
644
643
}
645
644
 
646
645
static void erase_cache(struct cache *cache, int type)
664
663
    slapi_counter_destroy(&cache->c_cursize);
665
664
    slapi_counter_destroy(&cache->c_hits);
666
665
    slapi_counter_destroy(&cache->c_tries);
667
 
    PR_DestroyLock(cache->c_mutex);
 
666
    PR_DestroyMonitor(cache->c_mutex);
668
667
    PR_DestroyLock(cache->c_emutexalloc_mutex);
669
668
}
670
669
 
688
687
                "WARNING -- Minimum cache size is %lu -- rounding up\n",
689
688
                MINCACHESIZE, 0, 0);
690
689
    }
691
 
    PR_Lock(cache->c_mutex);
 
690
    cache_lock(cache);
692
691
    cache->c_maxsize = bytes;
693
692
    LOG("entry cache size set to %lu\n", bytes, 0, 0);
694
693
    /* check for full cache, and clear out if necessary */
707
706
       erase_cache(cache, CACHE_TYPE_ENTRY);
708
707
       cache_make_hashes(cache, CACHE_TYPE_ENTRY);
709
708
    }
710
 
    PR_Unlock(cache->c_mutex);
 
709
    cache_unlock(cache);
711
710
    if (! dblayer_is_cachesize_sane(&bytes)) {
712
711
       LDAPDebug(LDAP_DEBUG_ANY,
713
712
                "WARNING -- Possible CONFIGURATION ERROR -- cachesize "
725
724
     * was given in # entries instead of memory footprint.  hopefully,
726
725
     * we can eventually drop this.
727
726
     */
728
 
    PR_Lock(cache->c_mutex);
 
727
    cache_lock(cache);
729
728
    cache->c_maxentries = entries;
730
729
    if (entries >= 0) {
731
730
        LOG("entry cache entry-limit set to %lu\n", entries, 0, 0);
736
735
    /* check for full cache, and clear out if necessary */
737
736
    if (CACHE_FULL(cache))
738
737
        eflush = entrycache_flush(cache);
739
 
    PR_Unlock(cache->c_mutex);
 
738
    cache_unlock(cache);
740
739
    while (eflush)
741
740
    {
742
741
        eflushtemp = BACK_LRU_NEXT(eflush, struct backentry *);
749
748
{
750
749
    size_t n = 0;
751
750
 
752
 
    PR_Lock(cache->c_mutex);
 
751
    cache_lock(cache);
753
752
    n = cache->c_maxsize;
754
 
    PR_Unlock(cache->c_mutex);
 
753
    cache_unlock(cache);
755
754
    return n;
756
755
}
757
756
 
759
758
{
760
759
    long n;
761
760
 
762
 
    PR_Lock(cache->c_mutex);
 
761
    cache_lock(cache);
763
762
    n = cache->c_maxentries;
764
 
    PR_Unlock(cache->c_mutex);
 
763
    cache_unlock(cache);
765
764
    return n;
766
765
}
767
766
 
787
786
                     long *nentries, long *maxentries,
788
787
                     size_t *size, size_t *maxsize)
789
788
{
790
 
    PR_Lock(cache->c_mutex);
 
789
    cache_lock(cache);
791
790
    if (hits) *hits = slapi_counter_get_value(cache->c_hits);
792
791
    if (tries) *tries = slapi_counter_get_value(cache->c_tries);
793
792
    if (nentries) *nentries = cache->c_curentries;
794
793
    if (maxentries) *maxentries = cache->c_maxentries;
795
794
    if (size) *size = slapi_counter_get_value(cache->c_cursize);
796
795
    if (maxsize) *maxsize = cache->c_maxsize;
797
 
    PR_Unlock(cache->c_mutex);
 
796
    cache_unlock(cache);
798
797
}
799
798
 
800
799
void cache_debug_hash(struct cache *cache, char **out)
805
804
    Hashtable *ht = NULL;
806
805
    char *name = "unknown";
807
806
 
808
 
    PR_Lock(cache->c_mutex);
 
807
    cache_lock(cache);
809
808
    *out = (char *)slapi_ch_malloc(1024);
810
809
    **out = 0;
811
810
 
841
840
            sprintf(*out + strlen(*out), "%d[%d] ", j, slot_stats[j]);
842
841
        slapi_ch_free((void **)&slot_stats);
843
842
    }
844
 
    PR_Unlock(cache->c_mutex);
 
843
    cache_unlock(cache);
845
844
}
846
845
 
847
846
 
947
946
    }
948
947
    e = (struct backcommon *)ptr;
949
948
 
950
 
    PR_Lock(cache->c_mutex);
 
949
    cache_lock(cache);
951
950
    if (CACHE_TYPE_ENTRY == e->ep_type) {
952
951
        ASSERT(e->ep_refcnt > 0);
953
952
        ret = entrycache_remove_int(cache, (struct backentry *)e);
954
953
    } else if (CACHE_TYPE_DN == e->ep_type) {
955
954
        ret = dncache_remove_int(cache, (struct backdn *)e);
956
955
    }
957
 
    PR_Unlock(cache->c_mutex);
 
956
    cache_unlock(cache);
958
957
    return ret;
959
958
}
960
959
 
1014
1013
#endif
1015
1014
    newndn = slapi_sdn_get_ndn(backentry_get_sdn(newe));
1016
1015
    entry_size = cache_entry_size(newe);
1017
 
    PR_Lock(cache->c_mutex);
 
1016
    cache_lock(cache);
1018
1017
 
1019
1018
    /*
1020
1019
     * First, remove the old entry from all the hashtables.
1034
1033
    }
1035
1034
    /* If fails, we have to make sure the both entires are removed from the cache,
1036
1035
     * otherwise, we have no idea what's left in the cache or not... */
1037
 
    if (!entry_same_dn(newe, (void *)oldndn) && (newe->ep_state & ENTRY_STATE_NOTINCACHE) == 0) {
 
1036
    if (cache_is_in_cache(cache, newe)) {
1038
1037
        /* if we're doing a modrdn or turning an entry to a tombstone,
1039
1038
         * the new entry can be in the dn table already, so we need to remove that too.
1040
1039
         */
1042
1041
        {
1043
1042
            slapi_counter_subtract(cache->c_cursize, newe->ep_size);
1044
1043
            cache->c_curentries--;
 
1044
            newe->ep_refcnt--;
1045
1045
            LOG("entry cache replace remove entry size %lu\n", newe->ep_size, 0, 0);
1046
1046
        }
1047
1047
    }
1064
1064
            LOG("entry cache replace (%s): cache index tables out of sync - found dn [%d] id [%d]\n",
1065
1065
                oldndn, found_in_dn, found_in_id);
1066
1066
#endif
1067
 
            PR_Unlock(cache->c_mutex);
 
1067
            cache_unlock(cache);
1068
1068
            return 1;
1069
1069
        }
1070
1070
    }
1073
1073
     * tested enough that we believe it works.)
1074
1074
     */
1075
1075
    if (!add_hash(cache->c_dntable, (void *)newndn, strlen(newndn), newe, (void **)&alte)) {
1076
 
       LOG("entry cache replace (%s): can't add to dn table (returned %s)\n", 
1077
 
           newndn, alte?slapi_entry_get_dn(alte->ep_entry):"none", 0);
1078
 
       PR_Unlock(cache->c_mutex);
1079
 
       return 1;
 
1076
        LOG("entry cache replace (%s): can't add to dn table (returned %s)\n", 
 
1077
            newndn, alte?slapi_entry_get_dn(alte->ep_entry):"none", 0);
 
1078
        cache_lock(cache);
 
1079
        return 1;
1080
1080
    }
1081
1081
    if (!add_hash(cache->c_idtable, &(newe->ep_id), sizeof(ID), newe, (void **)&alte)) {
1082
 
       LOG("entry cache replace (%s): can't add to id table (returned %s)\n", 
1083
 
           newndn, alte?slapi_entry_get_dn(alte->ep_entry):"none", 0);
1084
 
       if(remove_hash(cache->c_dntable, (void *)newndn, strlen(newndn)) == 0){
1085
 
           LOG("entry cache replace: failed to remove dn table\n", 0, 0, 0);
1086
 
       }
1087
 
       PR_Unlock(cache->c_mutex);
1088
 
       return 1;
 
1082
        LOG("entry cache replace (%s): can't add to id table (returned %s)\n", 
 
1083
            newndn, alte?slapi_entry_get_dn(alte->ep_entry):"none", 0);
 
1084
        if(remove_hash(cache->c_dntable, (void *)newndn, strlen(newndn)) == 0){
 
1085
            LOG("entry cache replace: failed to remove dn table\n", 0, 0, 0);
 
1086
        }
 
1087
        cache_unlock(cache);
 
1088
        return 1;
1089
1089
    }
1090
1090
#ifdef UUIDCACHE_ON 
1091
1091
    if (newuuid && !add_hash(cache->c_uuidtable, (void *)newuuid, strlen(newuuid),
1092
1092
                       newe, NULL)) {
1093
 
       LOG("entry cache replace: can't add uuid\n", 0, 0, 0);
1094
 
       if(remove_hash(cache->c_dntable, (void *)newndn, strlen(newndn)) == 0){
1095
 
           LOG("entry cache replace: failed to remove dn table(uuid cache)\n", 0, 0, 0);
1096
 
       }
1097
 
       if(remove_hash(cache->c_idtable, &(newe->ep_id), sizeof(ID)) == 0){
1098
 
           LOG("entry cache replace: failed to remove id table(uuid cache)\n", 0, 0, 0);
1099
 
       }
1100
 
       PR_Unlock(cache->c_mutex);
1101
 
       return 1;
 
1093
        LOG("entry cache replace: can't add uuid\n", 0, 0, 0);
 
1094
        if(remove_hash(cache->c_dntable, (void *)newndn, strlen(newndn)) == 0){
 
1095
            LOG("entry cache replace: failed to remove dn table(uuid cache)\n", 0, 0, 0);
 
1096
        }
 
1097
        if(remove_hash(cache->c_idtable, &(newe->ep_id), sizeof(ID)) == 0){
 
1098
            LOG("entry cache replace: failed to remove id table(uuid cache)\n", 0, 0, 0);
 
1099
        }
 
1100
        cache_unlock(cache);
 
1101
        return 1;
1102
1102
    }
1103
1103
#endif
1104
1104
    /* adjust cache meta info */
1110
1110
        slapi_counter_subtract(cache->c_cursize, olde->ep_size - newe->ep_size);
1111
1111
    }
1112
1112
    newe->ep_state = 0;
1113
 
    PR_Unlock(cache->c_mutex);
 
1113
    cache_unlock(cache);
1114
1114
    LOG("<= entrycache_replace OK,  cache size now %lu cache count now %ld\n",
1115
1115
             slapi_counter_get_value(cache->c_cursize), cache->c_curentries, 0);
1116
1116
    return 0;
1144
1144
    struct backentry *e;
1145
1145
 
1146
1146
    e = *bep;
 
1147
    if (!e) {
 
1148
        LDAPDebug0Args(LDAP_DEBUG_ANY, "entrycache_return e is NULL\n");
 
1149
        return;
 
1150
    }
1147
1151
    LOG("=> entrycache_return (%s) entry count: %d, entry in cache:%ld\n",
1148
1152
                    backentry_get_ndn(e), e->ep_refcnt, cache->c_curentries);
1149
1153
 
1150
 
    PR_Lock(cache->c_mutex);
 
1154
    cache_lock(cache);
1151
1155
    if (e->ep_state & ENTRY_STATE_NOTINCACHE)
1152
1156
    {
1153
1157
        backentry_free(bep);
1166
1170
            }
1167
1171
        }
1168
1172
    }
1169
 
    PR_Unlock(cache->c_mutex);
 
1173
    cache_unlock(cache);
1170
1174
    while (eflush)
1171
1175
    {
1172
1176
        eflushtemp = BACK_LRU_NEXT(eflush, struct backentry *);
1185
1189
    LOG("=> cache_find_dn (%s)\n", dn, 0, 0);
1186
1190
 
1187
1191
    /*entry normalized by caller (dn2entry.c)  */
1188
 
    PR_Lock(cache->c_mutex);
 
1192
    cache_lock(cache);
1189
1193
    if (find_hash(cache->c_dntable, (void *)dn, ndnlen, (void **)&e)) {
1190
1194
       /* need to check entry state */
1191
1195
       if (e->ep_state != 0) {
1192
1196
           /* entry is deleted or not fully created yet */
1193
 
           PR_Unlock(cache->c_mutex);
 
1197
           cache_unlock(cache);
1194
1198
           LOG("<= cache_find_dn (NOT FOUND)\n", 0, 0, 0);
1195
1199
           return NULL;
1196
1200
       }
1197
1201
       if (e->ep_refcnt == 0)
1198
1202
           lru_delete(cache, (void *)e);
1199
1203
       e->ep_refcnt++;
1200
 
       PR_Unlock(cache->c_mutex);
 
1204
       cache_unlock(cache);
1201
1205
       slapi_counter_increment(cache->c_hits);
1202
1206
    } else {
1203
 
       PR_Unlock(cache->c_mutex);
 
1207
       cache_unlock(cache);
1204
1208
    }
1205
1209
    slapi_counter_increment(cache->c_tries);
1206
1210
 
1216
1220
 
1217
1221
    LOG("=> cache_find_id (%lu)\n", (u_long)id, 0, 0);
1218
1222
 
1219
 
    PR_Lock(cache->c_mutex);
 
1223
    cache_lock(cache);
1220
1224
    if (find_hash(cache->c_idtable, &id, sizeof(ID), (void **)&e)) {
1221
1225
       /* need to check entry state */
1222
1226
       if (e->ep_state != 0) {
1223
1227
           /* entry is deleted or not fully created yet */
1224
 
           PR_Unlock(cache->c_mutex);
 
1228
           cache_unlock(cache);
1225
1229
           LOG("<= cache_find_id (NOT FOUND)\n", 0, 0, 0);
1226
1230
           return NULL;
1227
1231
       }
1228
1232
       if (e->ep_refcnt == 0)
1229
1233
           lru_delete(cache, (void *)e);
1230
1234
       e->ep_refcnt++;
1231
 
       PR_Unlock(cache->c_mutex);
 
1235
       cache_unlock(cache);
1232
1236
       slapi_counter_increment(cache->c_hits);
1233
1237
    } else {
1234
 
       PR_Unlock(cache->c_mutex);
 
1238
       cache_unlock(cache);
1235
1239
    }
1236
1240
    slapi_counter_increment(cache->c_tries);
1237
1241
 
1247
1251
 
1248
1252
    LOG("=> cache_find_uuid (%s)\n", uuid, 0, 0);
1249
1253
 
1250
 
    PR_Lock(cache->c_mutex);
 
1254
    cache_lock(cache);
1251
1255
    if (find_hash(cache->c_uuidtable, uuid, strlen(uuid), (void **)&e)) {
1252
1256
       /* need to check entry state */
1253
1257
       if (e->ep_state != 0) {
1254
1258
           /* entry is deleted or not fully created yet */
1255
 
           PR_Unlock(cache->c_mutex);
 
1259
           cache_unlock(cache);
1256
1260
           LOG("<= cache_find_uuid (NOT FOUND)\n", 0, 0, 0);
1257
1261
           return NULL;
1258
1262
       }
1259
1263
       if (e->ep_refcnt == 0)
1260
1264
           lru_delete(cache, (void *)e);
1261
1265
       e->ep_refcnt++;
1262
 
       PR_Unlock(cache->c_mutex);
 
1266
       cache_unlock(cache);
1263
1267
       slapi_counter_increment(cache->c_hits);
1264
1268
    } else {
1265
 
       PR_Unlock(cache->c_mutex);
 
1269
       cache_unlock(cache);
1266
1270
    }
1267
1271
    slapi_counter_increment(cache->c_tries);
1268
1272
 
1299
1303
        entry_size = e->ep_size;
1300
1304
    }
1301
1305
 
1302
 
    PR_Lock(cache->c_mutex);
 
1306
    cache_lock(cache);
1303
1307
    if (! add_hash(cache->c_dntable, (void *)ndn, strlen(ndn), e,
1304
1308
           (void **)&my_alt)) {
1305
1309
        LOG("entry \"%s\" already in dn cache\n", ndn, 0, 0);
1334
1338
                 * to prevent that the caller accidentally thinks the existing
1335
1339
                 * entry is not the same one the caller has and releases it.
1336
1340
                 */
1337
 
                PR_Unlock(cache->c_mutex);
 
1341
                cache_unlock(cache);
1338
1342
                return 1;
1339
1343
            }
1340
1344
        }
1344
1348
            {
1345
1349
                LOG("the entry %s is reserved (ep_state: 0x%x, state: 0x%x)\n", ndn, e->ep_state, state);
1346
1350
                e->ep_state |= ENTRY_STATE_NOTINCACHE;
1347
 
                PR_Unlock(cache->c_mutex);
 
1351
                cache_unlock(cache);
1348
1352
                return -1;
1349
1353
            }
1350
1354
            else if (state != 0)
1352
1356
                LOG("the entry %s already exists. cannot reserve it. (ep_state: 0x%x, state: 0x%x)\n",
1353
1357
                    ndn, e->ep_state, state);
1354
1358
                e->ep_state |= ENTRY_STATE_NOTINCACHE;
1355
 
                PR_Unlock(cache->c_mutex);
 
1359
                cache_unlock(cache);
1356
1360
                return -1;
1357
1361
            }
1358
1362
            else
1364
1368
                    (*alt)->ep_refcnt++;
1365
1369
                    LOG("the entry %s already exists.  returning existing entry %s (state: 0x%x)\n",
1366
1370
                        ndn, backentry_get_ndn(my_alt), state);
 
1371
                    cache_unlock(cache);
 
1372
                    return 1;
1367
1373
                } else {
1368
1374
                    LOG("the entry %s already exists.  Not returning existing entry %s (state: 0x%x)\n",
1369
1375
                        ndn, backentry_get_ndn(my_alt), state);
 
1376
                    cache_unlock(cache);
 
1377
                    return -1;
1370
1378
                }
1371
 
                PR_Unlock(cache->c_mutex);
1372
 
                return 1;
1373
1379
            }
1374
1380
        }
1375
1381
    }
1399
1405
                 * fine (i think).
1400
1406
                 */
1401
1407
                LOG("<= entrycache_add_int (ignoring)\n", 0, 0, 0);
1402
 
                PR_Unlock(cache->c_mutex);
 
1408
                cache_unlock(cache);
1403
1409
                return 0;
1404
1410
            }
1405
1411
            if(remove_hash(cache->c_dntable, (void *)ndn, strlen(ndn)) == 0){
1406
1412
                LOG("entrycache_add_int: failed to remove %s from dn table\n", 0, 0, 0);
1407
1413
            }
1408
1414
            e->ep_state |= ENTRY_STATE_NOTINCACHE;
1409
 
            PR_Unlock(cache->c_mutex);
 
1415
            cache_unlock(cache);
1410
1416
            LOG("entrycache_add_int: failed to add %s to cache (ep_state: %x, already_in: %d)\n",
1411
1417
                ndn, e->ep_state, already_in);
1412
1418
            return -1;
1425
1431
                    LOG("entrycache_add_int: failed to remove id table(uuid cache)\n", 0, 0, 0);
1426
1432
                }
1427
1433
                e->ep_state |= ENTRY_STATE_NOTINCACHE;
1428
 
                PR_Unlock(cache->c_mutex);
 
1434
                cache_unlock(cache);
1429
1435
                return -1;
1430
1436
            }
1431
1437
        }
1450
1456
        if (CACHE_FULL(cache))
1451
1457
            eflush = entrycache_flush(cache);
1452
1458
    }
1453
 
    PR_Unlock(cache->c_mutex);
 
1459
    cache_unlock(cache);
1454
1460
 
1455
1461
    while (eflush)
1456
1462
    {
1502
1508
}
1503
1509
void cache_lock(struct cache *cache)
1504
1510
{
1505
 
    PR_Lock(cache->c_mutex);
 
1511
    PR_EnterMonitor(cache->c_mutex);
1506
1512
}
1507
1513
void cache_unlock(struct cache *cache)
1508
1514
{
1509
 
    PR_Unlock(cache->c_mutex);
 
1515
    PR_ExitMonitor(cache->c_mutex);
1510
1516
}
1511
1517
 
1512
1518
/* locks an entry so that it can be modified (you should have gotten the
1540
1546
    PR_EnterMonitor(e->ep_mutexp);
1541
1547
 
1542
1548
    /* make sure entry hasn't been deleted now */
1543
 
    PR_Lock(cache->c_mutex);
 
1549
    cache_lock(cache);
1544
1550
    if (e->ep_state & (ENTRY_STATE_DELETED|ENTRY_STATE_NOTINCACHE)) {
1545
 
       PR_Unlock(cache->c_mutex);
 
1551
       cache_unlock(cache);
1546
1552
       PR_ExitMonitor(e->ep_mutexp);
1547
1553
       LOG("<= cache_lock_entry (DELETED)\n", 0, 0, 0);
1548
1554
       return RETRY_CACHE_LOCK;
1549
1555
    }
1550
 
    PR_Unlock(cache->c_mutex);
 
1556
    cache_unlock(cache);
1551
1557
 
1552
1558
    LOG("<= cache_lock_entry (FOUND)\n", 0, 0, 0);
1553
1559
    return 0;
1613
1619
                "WARNING -- Minimum cache size is %lu -- rounding up\n",
1614
1620
                MINCACHESIZE, 0, 0);
1615
1621
    }
1616
 
    PR_Lock(cache->c_mutex);
 
1622
    cache_lock(cache);
1617
1623
    cache->c_maxsize = bytes;
1618
1624
    LOG("entry cache size set to %lu\n", bytes, 0, 0);
1619
1625
    /* check for full cache, and clear out if necessary */
1633
1639
       erase_cache(cache, CACHE_TYPE_DN);
1634
1640
       cache_make_hashes(cache, CACHE_TYPE_DN);
1635
1641
    }
1636
 
    PR_Unlock(cache->c_mutex);
 
1642
    cache_unlock(cache);
1637
1643
    if (! dblayer_is_cachesize_sane(&bytes)) {
1638
1644
       LDAPDebug1Arg(LDAP_DEBUG_ANY,
1639
1645
                "WARNING -- Possible CONFIGURATION ERROR -- cachesize "
1697
1703
    LOG("=> dncache_return (%s) reference count: %d, dn in cache:%ld\n",
1698
1704
      slapi_sdn_get_dn((*bdn)->dn_sdn), (*bdn)->ep_refcnt, cache->c_curentries);
1699
1705
 
1700
 
    PR_Lock(cache->c_mutex);
 
1706
    cache_lock(cache);
1701
1707
    if ((*bdn)->ep_state & ENTRY_STATE_NOTINCACHE)
1702
1708
    {
1703
1709
        backdn_free(bdn);
1717
1723
            }
1718
1724
        }
1719
1725
    }
1720
 
    PR_Unlock(cache->c_mutex);
 
1726
    cache_unlock(cache);
1721
1727
    while (dnflush)
1722
1728
    {
1723
1729
        dnflushtemp = BACK_LRU_NEXT(dnflush, struct backdn *);
1738
1744
 
1739
1745
    LOG("=> dncache_find_id (%lu)\n", (u_long)id, 0, 0);
1740
1746
 
1741
 
    PR_Lock(cache->c_mutex);
 
1747
    cache_lock(cache);
1742
1748
    if (find_hash(cache->c_idtable, &id, sizeof(ID), (void **)&bdn)) {
1743
1749
       /* need to check entry state */
1744
1750
       if (bdn->ep_state != 0) {
1745
1751
           /* entry is deleted or not fully created yet */
1746
 
           PR_Unlock(cache->c_mutex);
 
1752
           cache_unlock(cache);
1747
1753
           LOG("<= dncache_find_id (NOT FOUND)\n", 0, 0, 0);
1748
1754
           return NULL;
1749
1755
       }
1750
1756
       if (bdn->ep_refcnt == 0)
1751
1757
           lru_delete(cache, (void *)bdn);
1752
1758
       bdn->ep_refcnt++;
1753
 
       PR_Unlock(cache->c_mutex);
 
1759
       cache_unlock(cache);
1754
1760
       slapi_counter_increment(cache->c_hits);
1755
1761
    } else {
1756
 
       PR_Unlock(cache->c_mutex);
 
1762
       cache_unlock(cache);
1757
1763
    }
1758
1764
    slapi_counter_increment(cache->c_tries);
1759
1765
 
1778
1784
    LOG("=> dncache_add_int( \"%s\", %ld )\n", slapi_sdn_get_dn(bdn->dn_sdn), 
1779
1785
        bdn->ep_id, 0);
1780
1786
 
1781
 
    PR_Lock(cache->c_mutex);
 
1787
    cache_lock(cache);
1782
1788
 
1783
1789
    if (! add_hash(cache->c_idtable, &(bdn->ep_id), sizeof(ID), bdn,
1784
1790
                                                           (void **)&my_alt)) {
1813
1819
                 * to prevent that the caller accidentally thinks the existing
1814
1820
                 * entry is not the same one the caller has and releases it.
1815
1821
                 */
1816
 
                PR_Unlock(cache->c_mutex);
 
1822
                cache_unlock(cache);
1817
1823
                return 1;
1818
1824
            }
1819
1825
        }
1823
1829
            {
1824
1830
                LOG("the entry is reserved\n", 0, 0, 0);
1825
1831
                bdn->ep_state |= ENTRY_STATE_NOTINCACHE;
1826
 
                PR_Unlock(cache->c_mutex);
 
1832
                cache_unlock(cache);
1827
1833
                return -1;
1828
1834
            }
1829
1835
            else if (state != 0)
1830
1836
            {
1831
1837
                LOG("the entry already exists. cannot reserve it.\n", 0, 0, 0);
1832
1838
                bdn->ep_state |= ENTRY_STATE_NOTINCACHE;
1833
 
                PR_Unlock(cache->c_mutex);
 
1839
                cache_unlock(cache);
1834
1840
                return -1;
1835
1841
            }
1836
1842
            else
1841
1847
                        lru_delete(cache, (void *)*alt);
1842
1848
                    (*alt)->ep_refcnt++;
1843
1849
                }
1844
 
                PR_Unlock(cache->c_mutex);
 
1850
                cache_unlock(cache);
1845
1851
                return 1;
1846
1852
            }
1847
1853
        }
1870
1876
            dnflush = dncache_flush(cache);
1871
1877
        }
1872
1878
    }
1873
 
    PR_Unlock(cache->c_mutex);
 
1879
    cache_unlock(cache);
1874
1880
 
1875
1881
    while (dnflush)
1876
1882
    {
1898
1904
     * where the entry isn't in all the table yet, so we don't care if any
1899
1905
     * of these return errors.
1900
1906
     */
1901
 
    PR_Lock(cache->c_mutex);
 
1907
    cache_lock(cache);
1902
1908
 
1903
1909
    /*
1904
1910
     * First, remove the old entry from the hashtable.
1910
1916
        found = remove_hash(cache->c_idtable, &(olddn->ep_id), sizeof(ID));
1911
1917
        if (!found) {
1912
1918
            LOG("dn cache replace: cache index tables out of sync\n", 0, 0, 0);
1913
 
            PR_Unlock(cache->c_mutex);
 
1919
            cache_unlock(cache);
1914
1920
            return 1;
1915
1921
        }
1916
1922
    }
1921
1927
     */
1922
1928
    if (!add_hash(cache->c_idtable, &(newdn->ep_id), sizeof(ID), newdn, NULL)) {
1923
1929
       LOG("dn cache replace: can't add id\n", 0, 0, 0);
1924
 
       PR_Unlock(cache->c_mutex);
 
1930
       cache_unlock(cache);
1925
1931
       return 1;
1926
1932
    }
1927
1933
    /* adjust cache meta info */
1936
1942
    }
1937
1943
    olddn->ep_state = ENTRY_STATE_DELETED;
1938
1944
    newdn->ep_state = 0;
1939
 
    PR_Unlock(cache->c_mutex);
 
1945
    cache_unlock(cache);
1940
1946
    LOG("<= dncache_replace OK,  cache size now %lu cache count now %ld\n",
1941
1947
             slapi_counter_get_value(cache->c_cursize), cache->c_curentries, 0);
1942
1948
    return 0;
2022
2028
 
2023
2029
#ifdef CACHE_DEBUG
2024
2030
void
2025
 
check_entry_cache(struct cache *cache, struct backentry *e, int in_cache)
 
2031
check_entry_cache(struct cache *cache, struct backentry *e)
2026
2032
{
2027
2033
        Slapi_DN *sdn = slapi_entry_get_sdn(e->ep_entry);
2028
2034
        struct backentry *debug_e = cache_find_dn(cache, 
2029
2035
                                                  slapi_sdn_get_dn(sdn),
2030
2036
                                                  slapi_sdn_get_ndn_len(sdn));
 
2037
        in_cache = cache_is_in_cache(cache, (void *)e);
2031
2038
        if (in_cache) {
2032
2039
                if (debug_e) { /* e is in cache */
2033
2040
                        CACHE_RETURN(cache, &debug_e);
2034
2041
                        if ((e != debug_e) && !(e->ep_state & ENTRY_STATE_DELETED)) {
2035
 
                                slapi_log_error(SLAPI_LOG_FATAL, "ldbm_back_delete",
 
2042
                                slapi_log_error(SLAPI_LOG_FATAL, "check_entry_cache",
2036
2043
                                                "entry 0x%p is not in dn cache but 0x%p having the same dn %s is "
2037
2044
                                                "although in_cache flag is set!!!\n",
2038
2045
                                                e, debug_e, slapi_sdn_get_dn(sdn));
2039
2046
                        }
2040
2047
                } else if (!(e->ep_state & ENTRY_STATE_DELETED)) {
2041
 
                        slapi_log_error(SLAPI_LOG_FATAL, "ldbm_back_delete",
 
2048
                        slapi_log_error(SLAPI_LOG_FATAL, "check_entry_cache",
2042
2049
                                        "%s (id %d) is not in dn cache although in_cache flag is set!!!\n",
2043
2050
                                        slapi_sdn_get_dn(sdn), e->ep_id);
2044
2051
                }
2046
2053
                if (debug_e) { /* e is in cache */
2047
2054
                        CACHE_RETURN(cache, &debug_e);
2048
2055
                        if ((e != debug_e) && !(e->ep_state & ENTRY_STATE_DELETED)) {
2049
 
                                slapi_log_error(SLAPI_LOG_FATAL, "ldbm_back_delete",
 
2056
                                slapi_log_error(SLAPI_LOG_FATAL, "check_entry_cache",
2050
2057
                                                "entry 0x%p is not in id cache but 0x%p having the same id %d is "
2051
2058
                                                "although in_cache flag is set!!!\n",
2052
2059
                                                e, debug_e, e->ep_id);
2053
2060
                        }
2054
2061
                } else {
2055
 
                        slapi_log_error(SLAPI_LOG_CACHE, "ldbm_back_delete",
 
2062
                        slapi_log_error(SLAPI_LOG_CACHE, "check_entry_cache",
2056
2063
                                        "%s (id %d) is not in id cache although in_cache flag is set!!!\n",
2057
2064
                                        slapi_sdn_get_dn(sdn), e->ep_id);
2058
2065
                }
2060
2067
                if (debug_e) { /* e is in cache */
2061
2068
                        CACHE_RETURN(cache, &debug_e);
2062
2069
                        if (e == debug_e) {
2063
 
                                slapi_log_error(SLAPI_LOG_FATAL, "ldbm_back_delete",
 
2070
                                slapi_log_error(SLAPI_LOG_FATAL, "check_entry_cache",
2064
2071
                                                "%s (id %d) is in dn cache although in_cache flag is not set!!!\n",
2065
2072
                                                slapi_sdn_get_dn(sdn), e->ep_id);
2066
2073
                        }
2069
2076
                if (debug_e) { /* e is in cache: bad */
2070
2077
                        CACHE_RETURN(cache, &debug_e);
2071
2078
                        if (e == debug_e) {
2072
 
                                slapi_log_error(SLAPI_LOG_CACHE, "ldbm_back_delete",
 
2079
                                slapi_log_error(SLAPI_LOG_CACHE, "check_entry_cache",
2073
2080
                                                "%s (id %d) is in id cache although in_cache flag is not set!!!\n",
2074
2081
                                                slapi_sdn_get_dn(sdn), e->ep_id);
2075
2082
                        }
2077
2084
        }
2078
2085
}
2079
2086
#endif
 
2087
 
 
2088
int
 
2089
cache_has_otherref(struct cache *cache, void *ptr)
 
2090
{
 
2091
    struct backcommon *bep;
 
2092
    int hasref = 0;
 
2093
 
 
2094
    if (NULL == ptr) {
 
2095
        return hasref;
 
2096
    }
 
2097
    bep = (struct backcommon *)ptr;
 
2098
    /* slows down too much? PR_Lock(cache->c_mutex); */
 
2099
    hasref = bep->ep_refcnt;
 
2100
    /* PR_Unlock(cache->c_mutex); */
 
2101
    return (hasref>1)?1:0;
 
2102
}
 
2103
 
 
2104
int
 
2105
cache_is_in_cache(struct cache *cache, void *ptr)
 
2106
{
 
2107
    struct backcommon *bep;
 
2108
    int in_cache = 0;
 
2109
 
 
2110
    if (NULL == ptr) {
 
2111
        return in_cache;
 
2112
    }
 
2113
    bep = (struct backcommon *)ptr;
 
2114
    /* slows down too much? PR_Lock(cache->c_mutex); */
 
2115
    in_cache = (bep->ep_state & (ENTRY_STATE_DELETED|ENTRY_STATE_NOTINCACHE))?0:1;
 
2116
    /* PR_Unlock(cache->c_mutex); */
 
2117
    return in_cache;
 
2118
}