1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
|
/*-
* Copyright (c) 2008-2014 WiredTiger, Inc.
* All rights reserved.
*
* See the file LICENSE for redistribution information.
*/
#include "wt_internal.h"
/*
* __wt_session_fotxn_add --
* Add a new entry into the session's free-on-transaction generation list.
*/
int
__wt_session_fotxn_add(WT_SESSION_IMPL *session, void *p, size_t len)
{
WT_FOTXN *fotxn;
size_t i;
/*
* Make sure the current thread has a transaction pinned so that
* we don't immediately free the memory we are stashing.
*/
WT_ASSERT(session,
WT_SESSION_TXN_STATE(session)->snap_min != WT_TXN_NONE);
/* Grow the list as necessary. */
WT_RET(__wt_realloc_def(session,
&session->fotxn_size, session->fotxn_cnt + 1, &session->fotxn));
/* Find an empty slot. */
for (i = 0, fotxn = session->fotxn;
i < session->fotxn_size / sizeof(session->fotxn[0]); ++i, ++fotxn)
if (fotxn->p == NULL) {
fotxn->txnid = S2C(session)->txn_global.current + 1;
WT_ASSERT(session,
!__wt_txn_visible_all(session, fotxn->txnid));
fotxn->p = p;
fotxn->len = len;
break;
}
++session->fotxn_cnt;
/* See if we can free any previous entries. */
if (session->fotxn_cnt > 1)
__wt_session_fotxn_discard(session, session, 0);
return (0);
}
/*
* __wt_session_fotxn_discard --
* Discard any memory from the session's free-on-transaction generation
* list that we can.
*/
void
__wt_session_fotxn_discard(WT_SESSION_IMPL *session_safe,
WT_SESSION_IMPL *session, int connection_close)
{
WT_FOTXN *fotxn;
size_t i;
/*
* This function is called during WT_CONNECTION.close to discard any
* memory that remains. For that reason, we take two WT_SESSION_IMPL
* arguments: session_safe is still linked to the WT_CONNECTION and
* can be safely used for calls to other WiredTiger functions, while
* session is the WT_SESSION_IMPL we're cleaning up.
*/
for (i = 0, fotxn = session->fotxn;
session->fotxn_cnt > 0 &&
i < session->fotxn_size / sizeof(session->fotxn[0]); ++i, ++fotxn)
if (fotxn->p != NULL && (connection_close ||
__wt_txn_visible_all(session_safe, fotxn->txnid))) {
--session->fotxn_cnt;
/*
* It's a bad thing if another thread is in this memory
* after we free it, make sure nothing good happens to
* that thread.
*/
__wt_overwrite_and_free_len(
session_safe, fotxn->p, fotxn->len);
}
if (connection_close)
__wt_free(session_safe, session->fotxn);
}
|