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