~drizzle-trunk/drizzle/development

1 by brian
clean slate
1
/* Copyright (C) 2000-2001, 2004-2005 MySQL AB
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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
16
17
#ifdef USE_PRAGMA_IMPLEMENTATION
18
#pragma implementation				// gcc: Class implementation
19
#endif
20
21
#include "mysql_priv.h"
22
#include <sys/stat.h>
23
#ifdef HAVE_SYS_MMAN_H
24
#include <sys/mman.h>
25
#endif
26
27
mapped_files::mapped_files(const char * filename,uchar *magic,uint magic_length)
28
{
29
#ifdef HAVE_MMAP
30
  name=my_strdup(filename,MYF(0));
31
  use_count=1;
32
  error=0;
33
  map=0;
34
  size=0;
35
  if ((file=my_open(name,O_RDONLY,MYF(MY_WME))) >= 0)
36
  {
37
    struct stat stat_buf;
38
    if (!fstat(file,&stat_buf))
39
    {
40
      if (!(map=(uchar*) my_mmap(0,(size_t)(size= stat_buf.st_size),PROT_READ,
41
			     MAP_SHARED | MAP_NORESERVE,file,
42
			     0L)))
43
      {
44
	error=errno;
45
	my_error(ER_NO_FILE_MAPPING, MYF(0), (char *) name, error);
46
      }
47
    }
48
    if (map && memcmp(map,magic,magic_length))
49
    {
50
      my_error(ER_WRONG_MAGIC, MYF(0), name);
51
      VOID(my_munmap((char*) map,(size_t)size));
52
      map=0;
53
    }
54
    if (!map)
55
    {
56
      VOID(my_close(file,MYF(0)));
57
      file= -1;
58
    }
59
  }
60
#endif
61
}
62
63
64
mapped_files::~mapped_files()
65
{
66
#ifdef HAVE_MMAP
67
  if (file >= 0)
68
  {
69
    VOID(my_munmap((char*) map,(size_t)size));
70
    VOID(my_close(file,MYF(0)));
71
    file= -1; map=0;
72
  }
73
  my_free(name,MYF(0));
74
#endif
75
}
76
77
78
static I_List<mapped_files> maps_in_use;
79
80
/*
81
**  Check if a file is mapped. If it is, then return pointer to old map,
82
**  else alloc new object
83
*/
84
85
mapped_files *map_file(const char * name,uchar *magic,uint magic_length)
86
{
87
#ifdef HAVE_MMAP
88
  VOID(pthread_mutex_lock(&LOCK_mapped_file));
89
  I_List_iterator<mapped_files> list(maps_in_use);
90
  mapped_files *map;
91
  char path[FN_REFLEN];
92
  sprintf(path,"%s/%s/%s.uniq",mysql_data_home,current_thd->db,name);
93
  (void) unpack_filename(path,path);
94
95
  while ((map=list++))
96
  {
97
    if (!strcmp(path,map->name))
98
      break;
99
  }
100
  if (!map)
101
  {
102
    map=new mapped_files(path,magic,magic_length);
103
    maps_in_use.append(map);
104
  }
105
  else
106
  {
107
    map->use_count++;
108
    if (!map->map)
109
      my_error(ER_NO_FILE_MAPPING, MYF(0), path, map->error);
110
  }
111
  VOID(pthread_mutex_unlock(&LOCK_mapped_file));
112
  return map;
113
#else
114
  return NULL;
115
#endif
116
}
117
118
/*
119
** free the map if there are no more users for it
120
*/
121
122
void unmap_file(mapped_files *map)
123
{
124
#ifdef HAVE_MMAP
125
  VOID(pthread_mutex_lock(&LOCK_mapped_file));
126
  if (!map->use_count--)
127
    delete map;
128
  VOID(pthread_mutex_unlock(&LOCK_mapped_file));
129
#endif
130
}
131
132
/*****************************************************************************
133
** Instansiate templates
134
*****************************************************************************/
135
136
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
137
/* Used templates */
138
template class I_List<mapped_files>;
139
template class I_List_iterator<mapped_files>;
140
#endif