MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
mi_close.c
1 /* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
2 
3  This program is free software; you can redistribute it and/or modify
4  it under the terms of the GNU General Public License as published by
5  the Free Software Foundation; version 2 of the License.
6 
7  This program is distributed in the hope that it will be useful,
8  but WITHOUT ANY WARRANTY; without even the implied warranty of
9  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  GNU General Public License for more details.
11 
12  You should have received a copy of the GNU General Public License
13  along with this program; if not, write to the Free Software
14  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
15 
16 /* close a isam-database */
17 /*
18  TODO:
19  We need to have a separate mutex on the closed file to allow other threads
20  to open other files during the time we flush the cache and close this file
21 */
22 
23 #include "myisamdef.h"
24 
25 int mi_close(register MI_INFO *info)
26 {
27  int error=0,flag;
28  MYISAM_SHARE *share=info->s;
29  DBUG_ENTER("mi_close");
30  DBUG_PRINT("enter",("base: 0x%lx reopen: %u locks: %u",
31  (long) info, (uint) share->reopen,
32  (uint) share->tot_locks));
33 
34  if (info->open_list.data)
35  mysql_mutex_lock(&THR_LOCK_myisam);
36  if (info->lock_type == F_EXTRA_LCK)
37  info->lock_type=F_UNLCK; /* HA_EXTRA_NO_USER_CHANGE */
38 
39  if (info->lock_type != F_UNLCK)
40  {
41  if (mi_lock_database(info,F_UNLCK))
42  error=my_errno;
43  }
44  mysql_mutex_lock(&share->intern_lock);
45 
46  if (share->options & HA_OPTION_READ_ONLY_DATA)
47  {
48  share->r_locks--;
49  share->tot_locks--;
50  }
51  if (info->opt_flag & (READ_CACHE_USED | WRITE_CACHE_USED))
52  {
53  if (end_io_cache(&info->rec_cache))
54  error=my_errno;
55  info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED);
56  }
57  flag= !--share->reopen;
58  if (info->open_list.data)
59  myisam_open_list= list_delete(myisam_open_list, &info->open_list);
60  mysql_mutex_unlock(&share->intern_lock);
61 
62  my_free(mi_get_rec_buff_ptr(info, info->rec_buff));
63  if (flag)
64  {
65  DBUG_EXECUTE_IF("crash_before_flush_keys",
66  if (share->kfile >= 0) abort(););
67  if (share->kfile >= 0 &&
68  flush_key_blocks(share->key_cache, share->kfile,
69  share->temporary ? FLUSH_IGNORE_CHANGED :
70  FLUSH_RELEASE))
71  error=my_errno;
72  if (share->kfile >= 0)
73  {
74  /*
75  If we are crashed, we can safely flush the current state as it will
76  not change the crashed state.
77  We can NOT write the state in other cases as other threads
78  may be using the file at this point
79  */
80  if (share->mode != O_RDONLY && mi_is_crashed(info))
81  mi_state_info_write(share->kfile, &share->state, 1);
82  /* Decrement open count must be last I/O on this file. */
83  _mi_decrement_open_count(info);
84  if (mysql_file_close(share->kfile, MYF(0)))
85  error = my_errno;
86  }
87 #ifdef HAVE_MMAP
88  if (share->file_map)
89  {
90  if (share->options & HA_OPTION_COMPRESS_RECORD)
91  _mi_unmap_file(info);
92  else
93  mi_munmap_file(info);
94  }
95 #endif
96  if (share->decode_trees)
97  {
98  my_free(share->decode_trees);
99  my_free(share->decode_tables);
100  }
101  thr_lock_delete(&share->lock);
102  mysql_mutex_destroy(&share->intern_lock);
103  {
104  int i,keys;
105  keys = share->state.header.keys;
106  mysql_rwlock_destroy(&share->mmap_lock);
107  for(i=0; i<keys; i++) {
108  mysql_rwlock_destroy(&share->key_root_lock[i]);
109  }
110  }
111  my_free(info->s);
112  }
113  if (info->open_list.data)
114  mysql_mutex_unlock(&THR_LOCK_myisam);
115  if (info->ftparser_param)
116  {
117  my_free(info->ftparser_param);
118  info->ftparser_param= 0;
119  }
120  if (info->dfile >= 0 && mysql_file_close(info->dfile, MYF(0)))
121  error = my_errno;
122 
123  myisam_log_command(MI_LOG_CLOSE,info,NULL,0,error);
124  my_free(info);
125 
126  if (error)
127  {
128  DBUG_RETURN(my_errno=error);
129  }
130  DBUG_RETURN(0);
131 } /* mi_close */