MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
table_sync_instances.cc
Go to the documentation of this file.
1 /* Copyright (c) 2008, 2010, 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 Foundation,
14  51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */
15 
22 #include "my_global.h"
23 #include "my_pthread.h"
24 #include "pfs_instr.h"
25 #include "pfs_column_types.h"
26 #include "pfs_column_values.h"
27 #include "table_sync_instances.h"
28 #include "pfs_global.h"
29 
30 THR_LOCK table_mutex_instances::m_table_lock;
31 
32 static const TABLE_FIELD_TYPE mutex_field_types[]=
33 {
34  {
35  { C_STRING_WITH_LEN("NAME") },
36  { C_STRING_WITH_LEN("varchar(128)") },
37  { NULL, 0}
38  },
39  {
40  { C_STRING_WITH_LEN("OBJECT_INSTANCE_BEGIN") },
41  { C_STRING_WITH_LEN("bigint(20)") },
42  { NULL, 0}
43  },
44  {
45  { C_STRING_WITH_LEN("LOCKED_BY_THREAD_ID") },
46  { C_STRING_WITH_LEN("bigint(20)") },
47  { NULL, 0}
48  }
49 };
50 
52 table_mutex_instances::m_field_def=
53 { 3, mutex_field_types };
54 
57 {
58  { C_STRING_WITH_LEN("mutex_instances") },
60  &table_mutex_instances::create,
61  NULL, /* write_row */
62  NULL, /* delete_all_rows */
63  NULL, /* get_row_count */
64  1000, /* records */
65  sizeof(PFS_simple_index),
66  &m_table_lock,
67  &m_field_def,
68  false /* checked */
69 };
70 
71 PFS_engine_table* table_mutex_instances::create(void)
72 {
73  return new table_mutex_instances();
74 }
75 
76 table_mutex_instances::table_mutex_instances()
77  : PFS_engine_table(&m_share, &m_pos),
78  m_row_exists(false), m_pos(0), m_next_pos(0)
79 {}
80 
82 {
83  m_pos.m_index= 0;
84  m_next_pos.m_index= 0;
85 }
86 
88 {
89  PFS_mutex *pfs;
90 
91  for (m_pos.set_at(&m_next_pos); m_pos.m_index < mutex_max; m_pos.next())
92  {
93  pfs= &mutex_array[m_pos.m_index];
94  if (pfs->m_lock.is_populated())
95  {
96  make_row(pfs);
97  m_next_pos.set_after(&m_pos);
98  return 0;
99  }
100  }
101 
102  return HA_ERR_END_OF_FILE;
103 }
104 
105 int table_mutex_instances::rnd_pos(const void *pos)
106 {
107  PFS_mutex *pfs;
108 
109  set_position(pos);
110  DBUG_ASSERT(m_pos.m_index < mutex_max);
111  pfs= &mutex_array[m_pos.m_index];
112  if (pfs->m_lock.is_populated())
113  {
114  make_row(pfs);
115  return 0;
116  }
117 
118  return HA_ERR_RECORD_DELETED;
119 }
120 
121 void table_mutex_instances::make_row(PFS_mutex *pfs)
122 {
123  pfs_lock lock;
124  PFS_mutex_class *safe_class;
125 
126  m_row_exists= false;
127 
128  /* Protect this reader against a mutex destroy */
129  pfs->m_lock.begin_optimistic_lock(&lock);
130 
131  safe_class= sanitize_mutex_class(pfs->m_class);
132  if (unlikely(safe_class == NULL))
133  return;
134 
135  m_row.m_name= safe_class->m_name;
136  m_row.m_name_length= safe_class->m_name_length;
137  m_row.m_identity= pfs->m_identity;
138 
139  /* Protect this reader against a mutex unlock */
140  PFS_thread *safe_owner= sanitize_thread(pfs->m_owner);
141  if (safe_owner)
142  {
143  m_row.m_locked_by_thread_id= safe_owner->m_thread_internal_id;
144  m_row.m_locked= true;
145  }
146  else
147  m_row.m_locked= false;
148 
149  if (pfs->m_lock.end_optimistic_lock(&lock))
150  m_row_exists= true;
151 }
152 
153 int table_mutex_instances::read_row_values(TABLE *table,
154  unsigned char *buf,
155  Field **fields,
156  bool read_all)
157 {
158  Field *f;
159 
160  if (unlikely(! m_row_exists))
161  return HA_ERR_RECORD_DELETED;
162 
163  /* Set the null bits */
164  DBUG_ASSERT(table->s->null_bytes == 1);
165  buf[0]= 0;
166 
167  for (; (f= *fields) ; fields++)
168  {
169  if (read_all || bitmap_is_set(table->read_set, f->field_index))
170  {
171  switch(f->field_index)
172  {
173  case 0: /* NAME */
175  break;
176  case 1: /* OBJECT_INSTANCE */
177  set_field_ulonglong(f, (intptr) m_row.m_identity);
178  break;
179  case 2: /* LOCKED_BY_THREAD_ID */
180  if (m_row.m_locked)
182  else
183  f->set_null();
184  break;
185  default:
186  DBUG_ASSERT(false);
187  }
188  }
189  }
190 
191  return 0;
192 }
193 
194 THR_LOCK table_rwlock_instances::m_table_lock;
195 
196 static const TABLE_FIELD_TYPE rwlock_field_types[]=
197 {
198  {
199  { C_STRING_WITH_LEN("NAME") },
200  { C_STRING_WITH_LEN("varchar(128)") },
201  { NULL, 0}
202  },
203  {
204  { C_STRING_WITH_LEN("OBJECT_INSTANCE_BEGIN") },
205  { C_STRING_WITH_LEN("bigint(20)") },
206  { NULL, 0}
207  },
208  {
209  { C_STRING_WITH_LEN("WRITE_LOCKED_BY_THREAD_ID") },
210  { C_STRING_WITH_LEN("bigint(20)") },
211  { NULL, 0}
212  },
213  {
214  { C_STRING_WITH_LEN("READ_LOCKED_BY_COUNT") },
215  { C_STRING_WITH_LEN("int(10)") },
216  { NULL, 0}
217  }
218 };
219 
221 table_rwlock_instances::m_field_def=
222 { 4, rwlock_field_types };
223 
226 {
227  { C_STRING_WITH_LEN("rwlock_instances") },
229  &table_rwlock_instances::create,
230  NULL, /* write_row */
231  NULL, /* delete_all_rows */
232  NULL, /* get_row_count */
233  1000, /* records */
234  sizeof(PFS_simple_index),
235  &m_table_lock,
236  &m_field_def,
237  false /* checked */
238 };
239 
240 PFS_engine_table* table_rwlock_instances::create(void)
241 {
242  return new table_rwlock_instances();
243 }
244 
245 table_rwlock_instances::table_rwlock_instances()
246  : PFS_engine_table(&m_share, &m_pos),
247  m_row_exists(false), m_pos(0), m_next_pos(0)
248 {}
249 
251 {
252  m_pos.m_index= 0;
253  m_next_pos.m_index= 0;
254 }
255 
257 {
258  PFS_rwlock *pfs;
259 
260  for (m_pos.set_at(&m_next_pos); m_pos.m_index < rwlock_max; m_pos.next())
261  {
262  pfs= &rwlock_array[m_pos.m_index];
263  if (pfs->m_lock.is_populated())
264  {
265  make_row(pfs);
266  m_next_pos.set_after(&m_pos);
267  return 0;
268  }
269  }
270 
271  return HA_ERR_END_OF_FILE;
272 }
273 
275 {
276  PFS_rwlock *pfs;
277 
278  set_position(pos);
279  DBUG_ASSERT(m_pos.m_index < rwlock_max);
280  pfs= &rwlock_array[m_pos.m_index];
281  if (pfs->m_lock.is_populated())
282  {
283  make_row(pfs);
284  return 0;
285  }
286 
287  return HA_ERR_RECORD_DELETED;
288 }
289 
290 void table_rwlock_instances::make_row(PFS_rwlock *pfs)
291 {
292  pfs_lock lock;
293  PFS_rwlock_class *safe_class;
294 
295  m_row_exists= false;
296 
297  /* Protect this reader against a rwlock destroy */
298  pfs->m_lock.begin_optimistic_lock(&lock);
299 
300  safe_class= sanitize_rwlock_class(pfs->m_class);
301  if (unlikely(safe_class == NULL))
302  return;
303 
304  m_row.m_name= safe_class->m_name;
305  m_row.m_name_length= safe_class->m_name_length;
306  m_row.m_identity= pfs->m_identity;
307 
308  /* Protect this reader against a rwlock unlock in the writer */
309  PFS_thread *safe_writer= sanitize_thread(pfs->m_writer);
310  if (safe_writer)
311  {
313  m_row.m_readers= 0;
314  m_row.m_write_locked= true;
315  }
316  else
317  {
318  m_row.m_readers= pfs->m_readers;
319  m_row.m_write_locked= false;
320  }
321 
322  if (pfs->m_lock.end_optimistic_lock(&lock))
323  m_row_exists= true;
324 }
325 
326 int table_rwlock_instances::read_row_values(TABLE *table,
327  unsigned char *buf,
328  Field **fields,
329  bool read_all)
330 {
331  Field *f;
332 
333  if (unlikely(! m_row_exists))
334  return HA_ERR_RECORD_DELETED;
335 
336  /* Set the null bits */
337  DBUG_ASSERT(table->s->null_bytes == 1);
338  buf[0]= 0;
339 
340  for (; (f= *fields) ; fields++)
341  {
342  if (read_all || bitmap_is_set(table->read_set, f->field_index))
343  {
344  switch(f->field_index)
345  {
346  case 0: /* NAME */
348  break;
349  case 1: /* OBJECT_INSTANCE */
350  set_field_ulonglong(f, (intptr) m_row.m_identity);
351  break;
352  case 2: /* WRITE_LOCKED_BY_THREAD_ID */
353  if (m_row.m_write_locked)
355  else
356  f->set_null();
357  break;
358  case 3: /* READ_LOCKED_BY_COUNT */
359  set_field_ulong(f, m_row.m_readers);
360  break;
361  default:
362  DBUG_ASSERT(false);
363  }
364  }
365  }
366 
367  return 0;
368 }
369 
370 THR_LOCK table_cond_instances::m_table_lock;
371 
372 static const TABLE_FIELD_TYPE cond_field_types[]=
373 {
374  {
375  { C_STRING_WITH_LEN("NAME") },
376  { C_STRING_WITH_LEN("varchar(128)") },
377  { NULL, 0}
378  },
379  {
380  { C_STRING_WITH_LEN("OBJECT_INSTANCE_BEGIN") },
381  { C_STRING_WITH_LEN("bigint(20)") },
382  { NULL, 0}
383  }
384 };
385 
387 table_cond_instances::m_field_def=
388 { 2, cond_field_types };
389 
392 {
393  { C_STRING_WITH_LEN("cond_instances") },
395  &table_cond_instances::create,
396  NULL, /* write_row */
397  NULL, /* delete_all_rows */
398  NULL, /* get_row_count */
399  1000, /* records */
400  sizeof(PFS_simple_index),
401  &m_table_lock,
402  &m_field_def,
403  false /* checked */
404 };
405 
406 PFS_engine_table* table_cond_instances::create(void)
407 {
408  return new table_cond_instances();
409 }
410 
411 table_cond_instances::table_cond_instances()
412  : PFS_engine_table(&m_share, &m_pos),
413  m_row_exists(false), m_pos(0), m_next_pos(0)
414 {}
415 
417 {
418  m_pos.m_index= 0;
419  m_next_pos.m_index= 0;
420 }
421 
423 {
424  PFS_cond *pfs;
425 
426  for (m_pos.set_at(&m_next_pos); m_pos.m_index < cond_max; m_pos.next())
427  {
428  pfs= &cond_array[m_pos.m_index];
429  if (pfs->m_lock.is_populated())
430  {
431  make_row(pfs);
432  m_next_pos.set_after(&m_pos);
433  return 0;
434  }
435  }
436 
437  return HA_ERR_END_OF_FILE;
438 }
439 
440 int table_cond_instances::rnd_pos(const void *pos)
441 {
442  PFS_cond *pfs;
443 
444  set_position(pos);
445  DBUG_ASSERT(m_pos.m_index < cond_max);
446  pfs= &cond_array[m_pos.m_index];
447  if (pfs->m_lock.is_populated())
448  {
449  make_row(pfs);
450  return 0;
451  }
452 
453  return HA_ERR_RECORD_DELETED;
454 }
455 
456 void table_cond_instances::make_row(PFS_cond *pfs)
457 {
458  pfs_lock lock;
459  PFS_cond_class *safe_class;
460 
461  m_row_exists= false;
462 
463  /* Protect this reader against a cond destroy */
464  pfs->m_lock.begin_optimistic_lock(&lock);
465 
466  safe_class= sanitize_cond_class(pfs->m_class);
467  if (unlikely(safe_class == NULL))
468  return;
469 
470  m_row.m_name= safe_class->m_name;
471  m_row.m_name_length= safe_class->m_name_length;
472  m_row.m_identity= pfs->m_identity;
473 
474  if (pfs->m_lock.end_optimistic_lock(&lock))
475  m_row_exists= true;
476 }
477 
478 int table_cond_instances::read_row_values(TABLE *table,
479  unsigned char *,
480  Field **fields,
481  bool read_all)
482 {
483  Field *f;
484 
485  if (unlikely(! m_row_exists))
486  return HA_ERR_RECORD_DELETED;
487 
488  /* Set the null bits */
489  DBUG_ASSERT(table->s->null_bytes == 0);
490 
491  for (; (f= *fields) ; fields++)
492  {
493  if (read_all || bitmap_is_set(table->read_set, f->field_index))
494  {
495  switch(f->field_index)
496  {
497  case 0: /* NAME */
499  break;
500  case 1: /* OBJECT_INSTANCE */
501  set_field_ulonglong(f, (intptr) m_row.m_identity);
502  break;
503  default:
504  DBUG_ASSERT(false);
505  }
506  }
507  }
508 
509  return 0;
510 }
511