1 /* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 // vim: ft=cpp:expandtab:ts=8:sw=4:softtabstop=4:
3 #ident "$Id$"
4 /*======
5 This file is part of PerconaFT.
6
7
8 Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
9
10 PerconaFT is free software: you can redistribute it and/or modify
11 it under the terms of the GNU General Public License, version 2,
12 as published by the Free Software Foundation.
13
14 PerconaFT is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with PerconaFT. If not, see <http://www.gnu.org/licenses/>.
21
22 ----------------------------------------
23
24 PerconaFT is free software: you can redistribute it and/or modify
25 it under the terms of the GNU Affero General Public License, version 3,
26 as published by the Free Software Foundation.
27
28 PerconaFT is distributed in the hope that it will be useful,
29 but WITHOUT ANY WARRANTY; without even the implied warranty of
30 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31 GNU Affero General Public License for more details.
32
33 You should have received a copy of the GNU Affero General Public License
34 along with PerconaFT. If not, see <http://www.gnu.org/licenses/>.
35 ======= */
36
37 #ident "Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved."
38
39 #include "test.h"
40
41 CACHEFILE f1;
42
pin_nonblocking(void * arg)43 static void *pin_nonblocking(void *arg) {
44 void* v1;
45 int r = toku_cachetable_get_and_pin_nonblocking(
46 f1,
47 make_blocknum(1),
48 toku_cachetable_hash(f1, make_blocknum(1)),
49 &v1,
50 def_write_callback(NULL), def_fetch, def_pf_req_callback, def_pf_callback,
51 PL_WRITE_EXPENSIVE,
52 NULL,
53 NULL
54 );
55 assert(r==TOKUDB_TRY_AGAIN);
56 return arg;
57 }
58
put_same_key(void * arg)59 static void *put_same_key(void *arg) {
60 toku_cachetable_put(
61 f1,
62 make_blocknum(1),
63 toku_cachetable_hash(f1,make_blocknum(1)),
64 NULL,
65 make_pair_attr(4),
66 def_write_callback(NULL),
67 put_callback_nop
68 );
69 return arg;
70 }
71
72 toku_pthread_t put_tid;
73
test_remove_key(CACHEKEY * UU (cachekey),bool UU (for_checkpoint),void * UU (extra))74 static void test_remove_key(CACHEKEY *UU(cachekey),
75 bool UU(for_checkpoint),
76 void *UU(extra)) {
77 int r = toku_pthread_create(
78 toku_uninstrumented, &put_tid, nullptr, put_same_key, nullptr);
79 assert_zero(r);
80 }
81
82 static void
cachetable_test(void)83 cachetable_test (void) {
84 const int test_limit = 12;
85 int r;
86 CACHETABLE ct;
87 toku_cachetable_create(&ct, test_limit, ZERO_LSN, nullptr);
88 const char *fname1 = TOKU_TEST_FILENAME;
89 unlink(fname1);
90 r = toku_cachetable_openf(&f1, ct, fname1, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r == 0);
91
92 void* v1;
93 r = toku_cachetable_get_and_pin(f1,
94 make_blocknum(1),
95 toku_cachetable_hash(f1, make_blocknum(1)),
96 &v1,
97 def_write_callback(nullptr),
98 def_fetch,
99 def_pf_req_callback,
100 def_pf_callback,
101 true,
102 nullptr);
103 toku_pthread_t pin_nonblocking_tid;
104 r = toku_pthread_create(toku_uninstrumented,
105 &pin_nonblocking_tid,
106 nullptr,
107 pin_nonblocking,
108 nullptr);
109 assert_zero(r);
110 // sleep 3 seconds
111 usleep(3 * 1024 * 1024);
112 r = toku_test_cachetable_unpin_and_remove(f1, make_blocknum(1), test_remove_key, NULL);
113 assert_zero(r);
114
115 void *ret;
116 r = toku_pthread_join(pin_nonblocking_tid, &ret);
117 assert_zero(r);
118 r = toku_pthread_join(put_tid, &ret);
119 assert_zero(r);
120
121 r = toku_test_cachetable_unpin(f1, make_blocknum(1), toku_cachetable_hash(f1, make_blocknum(1)), CACHETABLE_CLEAN, make_pair_attr(2));
122
123 toku_cachetable_verify(ct);
124 toku_cachefile_close(&f1, false, ZERO_LSN);
125 toku_cachetable_close(&ct);
126 }
127
128 int
test_main(int argc,const char * argv[])129 test_main(int argc, const char *argv[]) {
130 default_parse_args(argc, argv);
131 for (int i = 0; i < 20; i++) {
132 cachetable_test();
133 }
134 return 0;
135 }
136