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 // The helgrind2 test performs a DB->get() in two different concurrent threads.
41 #include <arpa/inet.h>
42 
43 #include <db.h>
44 #include <pthread.h>
45 #include <sys/stat.h>
46 #include <unistd.h>
47 #include <memory.h>
48 
49 DB_ENV *env;
50 DB *db;
51 
initialize(void)52 static void initialize (void) {
53     int r;
54     toku_os_recursive_delete(TOKU_TEST_FILENAME);
55     toku_os_mkdir(TOKU_TEST_FILENAME, 0777);
56 
57     // setup environment
58     {
59         r = db_env_create(&env, 0); assert(r == 0);
60 	r = env->set_redzone(env, 0);    CKERR(r);
61         env->set_errfile(env, stdout);
62         r = env->open(env, TOKU_TEST_FILENAME, DB_INIT_MPOOL + DB_PRIVATE + DB_CREATE, 0777);
63         assert(r == 0);
64     }
65 
66     // setup DB
67     {
68         DB_TXN *txn = 0;
69         r = db_create(&db, env, 0); assert(r == 0);
70         r = db->open(db, txn, "test.db", 0, DB_BTREE, DB_CREATE, 0777); assert(r == 0);
71     }
72 
73     // Put some stuff in
74     {
75         char v[10];
76         DB_TXN *txn = 0;
77         int i;
78 	const int n = 10;
79 	memset(v, 0, sizeof(v));
80         for (i=0; i<n; i++) {
81             int k = htonl(i);
82             DBT key, val;
83             r = db->put(db, txn, dbt_init(&key, &k, sizeof k), dbt_init(&val, v, sizeof(v)), 0);
84             assert(r == 0);
85         }
86     }
87 }
88 
finish(void)89 static void finish (void) {
90     int r;
91     r = db->close(db, 0); assert(r==0);
92     r = env->close(env, 0); assert(r==0);
93 }
94 
starta(void * ignore)95 static void *starta(void* ignore __attribute__((__unused__))) {
96     DB_TXN *txn = 0;
97     DBT key, val;
98     memset(&key, 0, sizeof(key));
99     memset(&val, 0, sizeof(val));
100     val.flags |= DB_DBT_MALLOC;
101     int k = htonl(0);
102     int r = db->get(db, txn, dbt_init(&key, &k, sizeof k), &val, 0);
103     assert(r==0);
104     //printf("val.data=%p\n", val.data);
105     int i; for (i=0; i<10; i++) assert(((char*)val.data)[i]==0);
106     toku_free(val.data);
107     return 0;
108 }
startb(void * ignore)109 static void *startb(void* ignore __attribute__((__unused__))) {
110     DB_TXN *txn = 0;
111     DBT key, val;
112     memset(&key, 0, sizeof(key));
113     memset(&val, 0, sizeof(val));
114     int k = htonl(0);
115     val.flags |= DB_DBT_MALLOC;
116     int r = db->get(db, txn, dbt_init(&key, &k, sizeof k), &val, 0);
117     assert(r==0);
118     //printf("val.data=%p\n", val.data);
119     int i; for (i=0; i<10; i++) assert(((char*)val.data)[i]==0);
120     toku_free(val.data);
121     return 0;
122 }
123 
124 int
test_main(int argc,char * const argv[])125 test_main (int argc, char * const argv[]) {
126     parse_args(argc, argv);
127     pthread_t a,b;
128     initialize();
129     { int x = pthread_create(&a, NULL, starta, NULL); assert(x==0); }
130     { int x = pthread_create(&b, NULL, startb, NULL); assert(x==0); }
131     { int x = pthread_join(a, NULL);           assert(x==0); }
132     { int x = pthread_join(b, NULL);           assert(x==0); }
133     finish();
134     return 0;
135 }
136