1 /* Copyright (c) 2010, 2021, Oracle and/or its affiliates.
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, version 2.0,
5   as published by the Free Software Foundation.
6 
7   This program is also distributed with certain software (including
8   but not limited to OpenSSL) that is licensed under separate terms,
9   as designated in a particular file or component or in included license
10   documentation.  The authors of MySQL hereby grant you an additional
11   permission to link the program and your derivative works with the
12   separately licensed software that they have included with MySQL.
13 
14   This program 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, version 2.0, for more details.
18 
19   You should have received a copy of the GNU General Public License
20   along with this program; if not, write to the Free Software Foundation,
21   51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */
22 
23 #include "my_global.h"
24 #include "my_sys.h"
25 #include "pfs_visitor.h"
26 #include "pfs_instr.h"
27 #include "pfs_instr_class.h"
28 #include "pfs_user.h"
29 #include "pfs_host.h"
30 #include "pfs_account.h"
31 #include "mysqld_thd_manager.h"
32 #include "pfs_buffer_container.h"
33 
34 /**
35   @file storage/perfschema/pfs_visitor.cc
36   Visitors (implementation).
37 */
38 
39 /**
40   @addtogroup Performance_schema_buffers
41   @{
42 */
43 
44 class All_THD_visitor_adapter : public Do_THD_Impl
45 {
46 public:
All_THD_visitor_adapter(PFS_connection_visitor * visitor)47   All_THD_visitor_adapter(PFS_connection_visitor *visitor)
48     : m_visitor(visitor)
49   {}
50 
operator ()(THD * thd)51   virtual void operator()(THD *thd)
52   {
53     m_visitor->visit_THD(thd);
54   }
55 
56 private:
57   PFS_connection_visitor *m_visitor;
58 };
59 
60 /** Connection iterator */
visit_global(bool with_hosts,bool with_users,bool with_accounts,bool with_threads,bool with_THDs,PFS_connection_visitor * visitor)61 void PFS_connection_iterator::visit_global(bool with_hosts, bool with_users,
62                                            bool with_accounts, bool with_threads,
63                                            bool with_THDs,
64                                            PFS_connection_visitor *visitor)
65 {
66   assert(visitor != NULL);
67   assert(! with_threads || ! with_THDs);
68 
69   visitor->visit_global();
70 
71   if (with_hosts)
72   {
73     PFS_host_iterator it= global_host_container.iterate();
74     PFS_host *pfs= it.scan_next();
75 
76     while (pfs != NULL)
77     {
78       visitor->visit_host(pfs);
79       pfs= it.scan_next();
80     }
81   }
82 
83   if (with_users)
84   {
85     PFS_user_iterator it= global_user_container.iterate();
86     PFS_user *pfs= it.scan_next();
87 
88     while (pfs != NULL)
89     {
90       visitor->visit_user(pfs);
91       pfs= it.scan_next();
92     }
93   }
94 
95   if (with_accounts)
96   {
97     PFS_account_iterator it= global_account_container.iterate();
98     PFS_account *pfs= it.scan_next();
99 
100     while (pfs != NULL)
101     {
102       visitor->visit_account(pfs);
103       pfs= it.scan_next();
104     }
105   }
106 
107 
108   if (with_threads)
109   {
110     PFS_thread_iterator it= global_thread_container.iterate();
111     PFS_thread *pfs= it.scan_next();
112 
113     while (pfs != NULL)
114     {
115       visitor->visit_thread(pfs);
116       pfs= it.scan_next();
117     }
118   }
119 
120   if (with_THDs)
121   {
122     All_THD_visitor_adapter adapter(visitor);
123     Global_THD_manager::get_instance()->do_for_all_thd(& adapter);
124   }
125 }
126 
127 class All_host_THD_visitor_adapter : public Do_THD_Impl
128 {
129 public:
All_host_THD_visitor_adapter(PFS_connection_visitor * visitor,PFS_host * host)130   All_host_THD_visitor_adapter(PFS_connection_visitor *visitor, PFS_host *host)
131     : m_visitor(visitor), m_host(host)
132   {}
133 
operator ()(THD * thd)134   virtual void operator()(THD *thd)
135   {
136     PSI_thread *psi= thd->get_psi();
137     PFS_thread *pfs= reinterpret_cast<PFS_thread*>(psi);
138     pfs= sanitize_thread(pfs);
139     if (pfs != NULL)
140     {
141       PFS_account *account= sanitize_account(pfs->m_account);
142       if (account != NULL)
143       {
144         if (account->m_host == m_host)
145         {
146           m_visitor->visit_THD(thd);
147         }
148       }
149       else if (pfs->m_host == m_host)
150       {
151         m_visitor->visit_THD(thd);
152       }
153     }
154   }
155 
156 private:
157   PFS_connection_visitor *m_visitor;
158   PFS_host *m_host;
159 };
160 
visit_host(PFS_host * host,bool with_accounts,bool with_threads,bool with_THDs,PFS_connection_visitor * visitor)161 void PFS_connection_iterator::visit_host(PFS_host *host,
162                                          bool with_accounts, bool with_threads,
163                                          bool with_THDs,
164                                          PFS_connection_visitor *visitor)
165 {
166   assert(visitor != NULL);
167   assert(! with_threads || ! with_THDs);
168 
169   visitor->visit_host(host);
170 
171   if (with_accounts)
172   {
173     PFS_account_iterator it= global_account_container.iterate();
174     PFS_account *pfs= it.scan_next();
175 
176     while (pfs != NULL)
177     {
178       if (pfs->m_host == host)
179       {
180         visitor->visit_account(pfs);
181       }
182       pfs= it.scan_next();
183     }
184   }
185 
186   if (with_threads)
187   {
188     PFS_thread_iterator it= global_thread_container.iterate();
189     PFS_thread *pfs= it.scan_next();
190 
191     while (pfs != NULL)
192     {
193       PFS_account *safe_account= sanitize_account(pfs->m_account);
194       if (((safe_account != NULL) && (safe_account->m_host == host)) /* 1 */
195           || (pfs->m_host == host))                                  /* 2 */
196       {
197         /*
198           If the thread belongs to:
199           - (1) a known user@host that belongs to this host,
200           - (2) a 'lost' user@host that belongs to this host
201           process it.
202         */
203         visitor->visit_thread(pfs);
204       }
205       pfs= it.scan_next();
206     }
207   }
208 
209   if (with_THDs)
210   {
211     All_host_THD_visitor_adapter adapter(visitor, host);
212     Global_THD_manager::get_instance()->do_for_all_thd(& adapter);
213   }
214 }
215 
216 class All_user_THD_visitor_adapter : public Do_THD_Impl
217 {
218 public:
All_user_THD_visitor_adapter(PFS_connection_visitor * visitor,PFS_user * user)219   All_user_THD_visitor_adapter(PFS_connection_visitor *visitor, PFS_user *user)
220     : m_visitor(visitor), m_user(user)
221   {}
222 
operator ()(THD * thd)223   virtual void operator()(THD *thd)
224   {
225     PSI_thread *psi= thd->get_psi();
226     PFS_thread *pfs= reinterpret_cast<PFS_thread*>(psi);
227     pfs= sanitize_thread(pfs);
228     if (pfs != NULL)
229     {
230       PFS_account *account= sanitize_account(pfs->m_account);
231       if (account != NULL)
232       {
233         if (account->m_user == m_user)
234         {
235           m_visitor->visit_THD(thd);
236         }
237       }
238       else if (pfs->m_user == m_user)
239       {
240         m_visitor->visit_THD(thd);
241       }
242     }
243   }
244 
245 private:
246   PFS_connection_visitor *m_visitor;
247   PFS_user *m_user;
248 };
249 
visit_user(PFS_user * user,bool with_accounts,bool with_threads,bool with_THDs,PFS_connection_visitor * visitor)250 void PFS_connection_iterator::visit_user(PFS_user *user,
251                                          bool with_accounts, bool with_threads,
252                                          bool with_THDs,
253                                          PFS_connection_visitor *visitor)
254 {
255   assert(visitor != NULL);
256   assert(! with_threads || ! with_THDs);
257 
258   visitor->visit_user(user);
259 
260   if (with_accounts)
261   {
262     PFS_account_iterator it= global_account_container.iterate();
263     PFS_account *pfs= it.scan_next();
264 
265     while (pfs != NULL)
266     {
267       if (pfs->m_user == user)
268       {
269         visitor->visit_account(pfs);
270       }
271       pfs= it.scan_next();
272     }
273   }
274 
275   if (with_threads)
276   {
277     PFS_thread_iterator it= global_thread_container.iterate();
278     PFS_thread *pfs= it.scan_next();
279 
280     while (pfs != NULL)
281     {
282       PFS_account *safe_account= sanitize_account(pfs->m_account);
283       if (((safe_account != NULL) && (safe_account->m_user == user)) /* 1 */
284           || (pfs->m_user == user))                                  /* 2 */
285       {
286         /*
287           If the thread belongs to:
288           - (1) a known user@host that belongs to this user,
289           - (2) a 'lost' user@host that belongs to this user
290           process it.
291         */
292         visitor->visit_thread(pfs);
293       }
294       pfs= it.scan_next();
295     }
296   }
297 
298   if (with_THDs)
299   {
300     All_user_THD_visitor_adapter adapter(visitor, user);
301     Global_THD_manager::get_instance()->do_for_all_thd(& adapter);
302   }
303 }
304 
305 class All_account_THD_visitor_adapter : public Do_THD_Impl
306 {
307 public:
All_account_THD_visitor_adapter(PFS_connection_visitor * visitor,PFS_account * account)308   All_account_THD_visitor_adapter(PFS_connection_visitor *visitor, PFS_account *account)
309     : m_visitor(visitor), m_account(account)
310   {}
311 
operator ()(THD * thd)312   virtual void operator()(THD *thd)
313   {
314     PSI_thread *psi= thd->get_psi();
315     PFS_thread *pfs= reinterpret_cast<PFS_thread*>(psi);
316     pfs= sanitize_thread(pfs);
317     if (pfs != NULL)
318     {
319       if (pfs->m_account == m_account)
320       {
321         m_visitor->visit_THD(thd);
322       }
323     }
324   }
325 
326 private:
327   PFS_connection_visitor *m_visitor;
328   PFS_account *m_account;
329 };
330 
visit_account(PFS_account * account,bool with_threads,bool with_THDs,PFS_connection_visitor * visitor)331 void PFS_connection_iterator::visit_account(PFS_account *account,
332                                             bool with_threads,
333                                             bool with_THDs,
334                                             PFS_connection_visitor *visitor)
335 {
336   assert(visitor != NULL);
337   assert(! with_threads || ! with_THDs);
338 
339   visitor->visit_account(account);
340 
341   if (with_threads)
342   {
343     PFS_thread_iterator it= global_thread_container.iterate();
344     PFS_thread *pfs= it.scan_next();
345 
346     while (pfs != NULL)
347     {
348       if (pfs->m_account == account)
349       {
350         visitor->visit_thread(pfs);
351       }
352       pfs= it.scan_next();
353     }
354   }
355 
356   if (with_THDs)
357   {
358     All_account_THD_visitor_adapter adapter(visitor, account);
359     Global_THD_manager::get_instance()->do_for_all_thd(& adapter);
360   }
361 }
362 
visit_THD(THD * thd,PFS_connection_visitor * visitor)363 void PFS_connection_iterator::visit_THD(THD *thd,
364                                         PFS_connection_visitor *visitor)
365 {
366   assert(visitor != NULL);
367   visitor->visit_THD(thd);
368 }
369 
visit_all(PFS_instance_visitor * visitor)370 void PFS_instance_iterator::visit_all(PFS_instance_visitor *visitor)
371 {
372   visit_all_mutex(visitor);
373   visit_all_rwlock(visitor);
374   visit_all_cond(visitor);
375   visit_all_file(visitor);
376 }
377 
visit_all_mutex(PFS_instance_visitor * visitor)378 void PFS_instance_iterator::visit_all_mutex(PFS_instance_visitor *visitor)
379 {
380   visit_all_mutex_classes(visitor);
381   visit_all_mutex_instances(visitor);
382 }
383 
visit_all_mutex_classes(PFS_instance_visitor * visitor)384 void PFS_instance_iterator::visit_all_mutex_classes(PFS_instance_visitor *visitor)
385 {
386   PFS_mutex_class *pfs= mutex_class_array;
387   PFS_mutex_class *pfs_last= pfs + mutex_class_max;
388   for ( ; pfs < pfs_last; pfs++)
389   {
390     if (pfs->m_name_length != 0)
391     {
392       visitor->visit_mutex_class(pfs);
393     }
394   }
395 }
396 
visit_all_mutex_instances(PFS_instance_visitor * visitor)397 void PFS_instance_iterator::visit_all_mutex_instances(PFS_instance_visitor *visitor)
398 {
399   PFS_mutex_iterator it= global_mutex_container.iterate();
400   PFS_mutex *pfs= it.scan_next();
401 
402   while (pfs != NULL)
403   {
404     visitor->visit_mutex(pfs);
405     pfs= it.scan_next();
406   }
407 }
408 
visit_all_rwlock(PFS_instance_visitor * visitor)409 void PFS_instance_iterator::visit_all_rwlock(PFS_instance_visitor *visitor)
410 {
411   visit_all_rwlock_classes(visitor);
412   visit_all_rwlock_instances(visitor);
413 }
414 
visit_all_rwlock_classes(PFS_instance_visitor * visitor)415 void PFS_instance_iterator::visit_all_rwlock_classes(PFS_instance_visitor *visitor)
416 {
417   PFS_rwlock_class *pfs= rwlock_class_array;
418   PFS_rwlock_class *pfs_last= pfs + rwlock_class_max;
419   for ( ; pfs < pfs_last; pfs++)
420   {
421     if (pfs->m_name_length != 0)
422     {
423       visitor->visit_rwlock_class(pfs);
424     }
425   }
426 }
427 
visit_all_rwlock_instances(PFS_instance_visitor * visitor)428 void PFS_instance_iterator::visit_all_rwlock_instances(PFS_instance_visitor *visitor)
429 {
430   PFS_rwlock_iterator it= global_rwlock_container.iterate();
431   PFS_rwlock *pfs= it.scan_next();
432 
433   while (pfs != NULL)
434   {
435     visitor->visit_rwlock(pfs);
436     pfs= it.scan_next();
437   }
438 }
439 
visit_all_cond(PFS_instance_visitor * visitor)440 void PFS_instance_iterator::visit_all_cond(PFS_instance_visitor *visitor)
441 {
442   visit_all_cond_classes(visitor);
443   visit_all_cond_instances(visitor);
444 }
445 
visit_all_cond_classes(PFS_instance_visitor * visitor)446 void PFS_instance_iterator::visit_all_cond_classes(PFS_instance_visitor *visitor)
447 {
448   PFS_cond_class *pfs= cond_class_array;
449   PFS_cond_class *pfs_last= pfs + cond_class_max;
450   for ( ; pfs < pfs_last; pfs++)
451   {
452     if (pfs->m_name_length != 0)
453     {
454       visitor->visit_cond_class(pfs);
455     }
456   }
457 }
458 
visit_all_cond_instances(PFS_instance_visitor * visitor)459 void PFS_instance_iterator::visit_all_cond_instances(PFS_instance_visitor *visitor)
460 {
461   PFS_cond_iterator it= global_cond_container.iterate();
462   PFS_cond *pfs= it.scan_next();
463 
464   while (pfs != NULL)
465   {
466     visitor->visit_cond(pfs);
467     pfs= it.scan_next();
468   }
469 }
470 
visit_all_file(PFS_instance_visitor * visitor)471 void PFS_instance_iterator::visit_all_file(PFS_instance_visitor *visitor)
472 {
473   visit_all_file_classes(visitor);
474   visit_all_file_instances(visitor);
475 }
476 
visit_all_file_classes(PFS_instance_visitor * visitor)477 void PFS_instance_iterator::visit_all_file_classes(PFS_instance_visitor *visitor)
478 {
479   PFS_file_class *pfs= file_class_array;
480   PFS_file_class *pfs_last= pfs + file_class_max;
481   for ( ; pfs < pfs_last; pfs++)
482   {
483     if (pfs->m_name_length != 0)
484     {
485       visitor->visit_file_class(pfs);
486     }
487   }
488 }
489 
visit_all_file_instances(PFS_instance_visitor * visitor)490 void PFS_instance_iterator::visit_all_file_instances(PFS_instance_visitor *visitor)
491 {
492   PFS_file_iterator it= global_file_container.iterate();
493   PFS_file *pfs= it.scan_next();
494 
495   while (pfs != NULL)
496   {
497     visitor->visit_file(pfs);
498     pfs= it.scan_next();
499   }
500 }
501 
502 /** Instance iterator */
503 
visit_mutex_instances(PFS_mutex_class * klass,PFS_instance_visitor * visitor)504 void PFS_instance_iterator::visit_mutex_instances(PFS_mutex_class *klass,
505                                                   PFS_instance_visitor *visitor)
506 {
507   assert(visitor != NULL);
508 
509   visitor->visit_mutex_class(klass);
510 
511   if (klass->is_singleton())
512   {
513     PFS_mutex *pfs= sanitize_mutex(klass->m_singleton);
514     if (likely(pfs != NULL))
515     {
516       if (likely(pfs->m_lock.is_populated()))
517       {
518         visitor->visit_mutex(pfs);
519       }
520     }
521   }
522   else
523   {
524     PFS_mutex_iterator it= global_mutex_container.iterate();
525     PFS_mutex *pfs= it.scan_next();
526 
527     while (pfs != NULL)
528     {
529       if (pfs->m_class == klass)
530       {
531         visitor->visit_mutex(pfs);
532       }
533       pfs= it.scan_next();
534     }
535   }
536 }
537 
visit_rwlock_instances(PFS_rwlock_class * klass,PFS_instance_visitor * visitor)538 void PFS_instance_iterator::visit_rwlock_instances(PFS_rwlock_class *klass,
539                                                    PFS_instance_visitor *visitor)
540 {
541   assert(visitor != NULL);
542 
543   visitor->visit_rwlock_class(klass);
544 
545   if (klass->is_singleton())
546   {
547     PFS_rwlock *pfs= sanitize_rwlock(klass->m_singleton);
548     if (likely(pfs != NULL))
549     {
550       if (likely(pfs->m_lock.is_populated()))
551       {
552         visitor->visit_rwlock(pfs);
553       }
554     }
555   }
556   else
557   {
558     PFS_rwlock_iterator it= global_rwlock_container.iterate();
559     PFS_rwlock *pfs= it.scan_next();
560 
561     while (pfs != NULL)
562     {
563       if (pfs->m_class == klass)
564       {
565         visitor->visit_rwlock(pfs);
566       }
567       pfs= it.scan_next();
568     }
569   }
570 }
571 
visit_cond_instances(PFS_cond_class * klass,PFS_instance_visitor * visitor)572 void PFS_instance_iterator::visit_cond_instances(PFS_cond_class *klass,
573                                                  PFS_instance_visitor *visitor)
574 {
575   assert(visitor != NULL);
576 
577   visitor->visit_cond_class(klass);
578 
579   if (klass->is_singleton())
580   {
581     PFS_cond *pfs= sanitize_cond(klass->m_singleton);
582     if (likely(pfs != NULL))
583     {
584       if (likely(pfs->m_lock.is_populated()))
585       {
586         visitor->visit_cond(pfs);
587       }
588     }
589   }
590   else
591   {
592     PFS_cond_iterator it= global_cond_container.iterate();
593     PFS_cond *pfs= it.scan_next();
594 
595     while (pfs != NULL)
596     {
597       if (pfs->m_class == klass)
598       {
599         visitor->visit_cond(pfs);
600       }
601       pfs= it.scan_next();
602     }
603   }
604 }
605 
visit_file_instances(PFS_file_class * klass,PFS_instance_visitor * visitor)606 void PFS_instance_iterator::visit_file_instances(PFS_file_class *klass,
607                                                  PFS_instance_visitor *visitor)
608 {
609   assert(visitor != NULL);
610 
611   visitor->visit_file_class(klass);
612 
613   if (klass->is_singleton())
614   {
615     PFS_file *pfs= sanitize_file(klass->m_singleton);
616     if (likely(pfs != NULL))
617     {
618       if (likely(pfs->m_lock.is_populated()))
619       {
620         visitor->visit_file(pfs);
621       }
622     }
623   }
624   else
625   {
626     PFS_file_iterator it= global_file_container.iterate();
627     PFS_file *pfs= it.scan_next();
628 
629     while (pfs != NULL)
630     {
631       if (pfs->m_class == klass)
632       {
633         visitor->visit_file(pfs);
634       }
635       pfs= it.scan_next();
636     }
637   }
638 }
639 
640 /** Socket instance iterator visting a socket class and all instances */
641 
visit_socket_instances(PFS_socket_class * klass,PFS_instance_visitor * visitor)642 void PFS_instance_iterator::visit_socket_instances(PFS_socket_class *klass,
643                                                    PFS_instance_visitor *visitor)
644 {
645   assert(visitor != NULL);
646 
647   visitor->visit_socket_class(klass);
648 
649   if (klass->is_singleton())
650   {
651     PFS_socket *pfs= sanitize_socket(klass->m_singleton);
652     if (likely(pfs != NULL))
653     {
654       if (likely(pfs->m_lock.is_populated()))
655       {
656         visitor->visit_socket(pfs);
657       }
658     }
659   }
660   else
661   {
662     PFS_socket_iterator it= global_socket_container.iterate();
663     PFS_socket *pfs= it.scan_next();
664 
665     while (pfs != NULL)
666     {
667       if (pfs->m_class == klass)
668       {
669         visitor->visit_socket(pfs);
670       }
671       pfs= it.scan_next();
672     }
673   }
674 }
675 
676 /** Socket instance iterator visting sockets owned by PFS_thread. */
677 
visit_socket_instances(PFS_socket_class * klass,PFS_instance_visitor * visitor,PFS_thread * thread,bool visit_class)678 void PFS_instance_iterator::visit_socket_instances(PFS_socket_class *klass,
679                                                    PFS_instance_visitor *visitor,
680                                                    PFS_thread *thread,
681                                                    bool visit_class)
682 {
683   assert(visitor != NULL);
684   assert(thread != NULL);
685 
686   if (visit_class)
687     visitor->visit_socket_class(klass);
688 
689   if (klass->is_singleton())
690   {
691     PFS_socket *pfs= sanitize_socket(klass->m_singleton);
692     if (likely(pfs != NULL))
693     {
694       if (unlikely(pfs->m_thread_owner == thread))
695         visitor->visit_socket(pfs);
696     }
697   }
698   else
699   {
700     /* Get current socket stats from each socket instance owned by this thread */
701     PFS_socket_iterator it= global_socket_container.iterate();
702     PFS_socket *pfs= it.scan_next();
703 
704     while (pfs != NULL)
705     {
706       if (unlikely((pfs->m_class == klass) &&
707                    (pfs->m_thread_owner == thread)))
708       {
709         visitor->visit_socket(pfs);
710       }
711       pfs= it.scan_next();
712     }
713   }
714 }
715 
716 /** Generic instance iterator with PFS_thread as matching criteria */
717 
visit_instances(PFS_instr_class * klass,PFS_instance_visitor * visitor,PFS_thread * thread,bool visit_class)718 void PFS_instance_iterator::visit_instances(PFS_instr_class *klass,
719                                             PFS_instance_visitor *visitor,
720                                             PFS_thread *thread,
721                                             bool visit_class)
722 {
723   assert(visitor != NULL);
724   assert(klass != NULL);
725 
726   switch (klass->m_type)
727   {
728   case PFS_CLASS_SOCKET:
729     {
730     PFS_socket_class *socket_class= reinterpret_cast<PFS_socket_class*>(klass);
731     PFS_instance_iterator::visit_socket_instances(socket_class, visitor,
732                                                   thread, visit_class);
733     }
734     break;
735   default:
736     break;
737   }
738 }
739 
740 /** Object iterator */
visit_all(PFS_object_visitor * visitor)741 void PFS_object_iterator::visit_all(PFS_object_visitor *visitor)
742 {
743   visit_all_tables(visitor);
744 }
745 
746 class Proc_all_table_shares
747   : public PFS_buffer_processor<PFS_table_share>
748 {
749 public:
Proc_all_table_shares(PFS_object_visitor * visitor)750   Proc_all_table_shares(PFS_object_visitor *visitor)
751     : m_visitor(visitor)
752   {}
753 
operator ()(PFS_table_share * pfs)754   virtual void operator()(PFS_table_share *pfs)
755   {
756     if (pfs->m_enabled)
757     {
758       m_visitor->visit_table_share(pfs);
759     }
760   }
761 
762 private:
763   PFS_object_visitor* m_visitor;
764 };
765 
766 class Proc_all_table_handles
767   : public PFS_buffer_processor<PFS_table>
768 {
769 public:
Proc_all_table_handles(PFS_object_visitor * visitor)770   Proc_all_table_handles(PFS_object_visitor *visitor)
771     : m_visitor(visitor)
772   {}
773 
operator ()(PFS_table * pfs)774   virtual void operator()(PFS_table *pfs)
775   {
776     PFS_table_share *safe_share= sanitize_table_share(pfs->m_share);
777     if (safe_share != NULL)
778     {
779       if (safe_share->m_enabled)
780       {
781         m_visitor->visit_table(pfs);
782       }
783     }
784   }
785 
786 private:
787   PFS_object_visitor* m_visitor;
788 };
789 
visit_all_tables(PFS_object_visitor * visitor)790 void PFS_object_iterator::visit_all_tables(PFS_object_visitor *visitor)
791 {
792   assert(visitor != NULL);
793 
794   visitor->visit_global();
795 
796   /* For all the table shares ... */
797   Proc_all_table_shares proc_shares(visitor);
798   global_table_share_container.apply(proc_shares);
799 
800   /* For all the table handles ... */
801   Proc_all_table_handles proc_handles(visitor);
802   global_table_container.apply(proc_handles);
803 }
804 
805 class Proc_one_table_share_handles
806   : public PFS_buffer_processor<PFS_table>
807 {
808 public:
Proc_one_table_share_handles(PFS_object_visitor * visitor,PFS_table_share * share)809   Proc_one_table_share_handles(PFS_object_visitor *visitor, PFS_table_share *share)
810     : m_visitor(visitor), m_share(share)
811   {}
812 
operator ()(PFS_table * pfs)813   virtual void operator()(PFS_table *pfs)
814   {
815     if (pfs->m_share == m_share)
816     {
817       m_visitor->visit_table(pfs);
818     }
819   }
820 
821 private:
822   PFS_object_visitor* m_visitor;
823   PFS_table_share* m_share;
824 };
825 
visit_tables(PFS_table_share * share,PFS_object_visitor * visitor)826 void PFS_object_iterator::visit_tables(PFS_table_share *share,
827                                        PFS_object_visitor *visitor)
828 {
829   assert(visitor != NULL);
830 
831   if (!share->m_enabled)
832     return;
833 
834   visitor->visit_table_share(share);
835 
836 #ifdef LATER
837   if (share->get_refcount() == 0)
838     return;
839 #endif
840 
841   /* For all the table handles ... */
842   Proc_one_table_share_handles proc(visitor, share);
843   global_table_container.apply(proc);
844 }
845 
846 class Proc_one_table_share_indexes
847   : public PFS_buffer_processor<PFS_table>
848 {
849 public:
Proc_one_table_share_indexes(PFS_object_visitor * visitor,PFS_table_share * share,uint index)850   Proc_one_table_share_indexes(PFS_object_visitor *visitor, PFS_table_share *share, uint index)
851     : m_visitor(visitor), m_share(share), m_index(index)
852   {}
853 
operator ()(PFS_table * pfs)854   virtual void operator()(PFS_table *pfs)
855   {
856     if (pfs->m_share == m_share)
857     {
858       m_visitor->visit_table_index(pfs, m_index);
859     }
860   }
861 
862 private:
863   PFS_object_visitor* m_visitor;
864   PFS_table_share* m_share;
865   uint m_index;
866 };
867 
visit_table_indexes(PFS_table_share * share,uint index,PFS_object_visitor * visitor)868 void PFS_object_iterator::visit_table_indexes(PFS_table_share *share,
869                                               uint index,
870                                               PFS_object_visitor *visitor)
871 {
872   assert(visitor != NULL);
873 
874   if (!share->m_enabled)
875     return;
876 
877   visitor->visit_table_share_index(share, index);
878 
879 #ifdef LATER
880   if (share->get_refcount() == 0)
881     return;
882 #endif
883 
884   /* For all the table handles ... */
885   Proc_one_table_share_indexes proc(visitor, share, index);
886   global_table_container.apply(proc);
887 }
888 
889 /** Connection wait visitor */
890 
891 PFS_connection_wait_visitor
PFS_connection_wait_visitor(PFS_instr_class * klass)892 ::PFS_connection_wait_visitor(PFS_instr_class *klass)
893 {
894   m_index= klass->m_event_name_index;
895 }
896 
~PFS_connection_wait_visitor()897 PFS_connection_wait_visitor::~PFS_connection_wait_visitor()
898 {}
899 
visit_global()900 void PFS_connection_wait_visitor::visit_global()
901 {
902   /*
903     This visitor is used only for global instruments
904     that do not have instances.
905     For waits, do not sum by connection but by instances,
906     it is more efficient.
907   */
908   assert(   (m_index == global_idle_class.m_event_name_index)
909             || (m_index == global_metadata_class.m_event_name_index));
910 
911   if (m_index == global_idle_class.m_event_name_index)
912   {
913     m_stat.aggregate(& global_idle_stat);
914   }
915   else
916   {
917     m_stat.aggregate(& global_metadata_stat);
918   }
919 }
920 
visit_host(PFS_host * pfs)921 void PFS_connection_wait_visitor::visit_host(PFS_host *pfs)
922 {
923   const PFS_single_stat *event_name_array;
924   event_name_array= pfs->read_instr_class_waits_stats();
925   if (event_name_array != NULL)
926   {
927     m_stat.aggregate(& event_name_array[m_index]);
928   }
929 }
930 
visit_user(PFS_user * pfs)931 void PFS_connection_wait_visitor::visit_user(PFS_user *pfs)
932 {
933   const PFS_single_stat *event_name_array;
934   event_name_array= pfs->read_instr_class_waits_stats();
935   if (event_name_array != NULL)
936   {
937     m_stat.aggregate(& event_name_array[m_index]);
938   }
939 }
940 
visit_account(PFS_account * pfs)941 void PFS_connection_wait_visitor::visit_account(PFS_account *pfs)
942 {
943   const PFS_single_stat *event_name_array;
944   event_name_array= pfs->read_instr_class_waits_stats();
945   if (event_name_array != NULL)
946   {
947     m_stat.aggregate(& event_name_array[m_index]);
948   }
949 }
950 
visit_thread(PFS_thread * pfs)951 void PFS_connection_wait_visitor::visit_thread(PFS_thread *pfs)
952 {
953   const PFS_single_stat *event_name_array;
954   event_name_array= pfs->read_instr_class_waits_stats();
955   if (event_name_array != NULL)
956   {
957     m_stat.aggregate(& event_name_array[m_index]);
958   }
959 }
960 
961 PFS_connection_all_wait_visitor
PFS_connection_all_wait_visitor()962 ::PFS_connection_all_wait_visitor()
963 {}
964 
~PFS_connection_all_wait_visitor()965 PFS_connection_all_wait_visitor::~PFS_connection_all_wait_visitor()
966 {}
967 
visit_global()968 void PFS_connection_all_wait_visitor::visit_global()
969 {
970   /* Sum by instances, not by connection */
971   assert(false);
972 }
973 
visit_connection_slice(PFS_connection_slice * pfs)974 void PFS_connection_all_wait_visitor::visit_connection_slice(PFS_connection_slice *pfs)
975 {
976   const PFS_single_stat *stat= pfs->read_instr_class_waits_stats();
977   if (stat != NULL)
978   {
979     const PFS_single_stat *stat_last= stat + wait_class_max;
980     for ( ; stat < stat_last; stat++)
981     {
982       m_stat.aggregate(stat);
983     }
984   }
985 }
986 
visit_host(PFS_host * pfs)987 void PFS_connection_all_wait_visitor::visit_host(PFS_host *pfs)
988 {
989   visit_connection_slice(pfs);
990 }
991 
visit_user(PFS_user * pfs)992 void PFS_connection_all_wait_visitor::visit_user(PFS_user *pfs)
993 {
994   visit_connection_slice(pfs);
995 }
996 
visit_account(PFS_account * pfs)997 void PFS_connection_all_wait_visitor::visit_account(PFS_account *pfs)
998 {
999   visit_connection_slice(pfs);
1000 }
1001 
visit_thread(PFS_thread * pfs)1002 void PFS_connection_all_wait_visitor::visit_thread(PFS_thread *pfs)
1003 {
1004   visit_connection_slice(pfs);
1005 }
1006 
PFS_connection_stage_visitor(PFS_stage_class * klass)1007 PFS_connection_stage_visitor::PFS_connection_stage_visitor(PFS_stage_class *klass)
1008 {
1009   m_index= klass->m_event_name_index;
1010 }
1011 
~PFS_connection_stage_visitor()1012 PFS_connection_stage_visitor::~PFS_connection_stage_visitor()
1013 {}
1014 
visit_global()1015 void PFS_connection_stage_visitor::visit_global()
1016 {
1017   m_stat.aggregate(& global_instr_class_stages_array[m_index]);
1018 }
1019 
visit_host(PFS_host * pfs)1020 void PFS_connection_stage_visitor::visit_host(PFS_host *pfs)
1021 {
1022   const PFS_stage_stat *event_name_array;
1023   event_name_array= pfs->read_instr_class_stages_stats();
1024   if (event_name_array != NULL)
1025   {
1026     m_stat.aggregate(& event_name_array[m_index]);
1027   }
1028 }
1029 
visit_user(PFS_user * pfs)1030 void PFS_connection_stage_visitor::visit_user(PFS_user *pfs)
1031 {
1032   const PFS_stage_stat *event_name_array;
1033   event_name_array= pfs->read_instr_class_stages_stats();
1034   if (event_name_array != NULL)
1035   {
1036     m_stat.aggregate(& event_name_array[m_index]);
1037   }
1038 }
1039 
visit_account(PFS_account * pfs)1040 void PFS_connection_stage_visitor::visit_account(PFS_account *pfs)
1041 {
1042   const PFS_stage_stat *event_name_array;
1043   event_name_array= pfs->read_instr_class_stages_stats();
1044   if (event_name_array != NULL)
1045   {
1046     m_stat.aggregate(& event_name_array[m_index]);
1047   }
1048 }
1049 
visit_thread(PFS_thread * pfs)1050 void PFS_connection_stage_visitor::visit_thread(PFS_thread *pfs)
1051 {
1052   const PFS_stage_stat *event_name_array;
1053   event_name_array= pfs->read_instr_class_stages_stats();
1054   if (event_name_array != NULL)
1055   {
1056     m_stat.aggregate(& event_name_array[m_index]);
1057   }
1058 }
1059 
1060 PFS_connection_statement_visitor
PFS_connection_statement_visitor(PFS_statement_class * klass)1061 ::PFS_connection_statement_visitor(PFS_statement_class *klass)
1062 {
1063   m_index= klass->m_event_name_index;
1064 }
1065 
~PFS_connection_statement_visitor()1066 PFS_connection_statement_visitor::~PFS_connection_statement_visitor()
1067 {}
1068 
visit_global()1069 void PFS_connection_statement_visitor::visit_global()
1070 {
1071   m_stat.aggregate(& global_instr_class_statements_array[m_index]);
1072 }
1073 
visit_host(PFS_host * pfs)1074 void PFS_connection_statement_visitor::visit_host(PFS_host *pfs)
1075 {
1076   const PFS_statement_stat *event_name_array;
1077   event_name_array= pfs->read_instr_class_statements_stats();
1078   if (event_name_array != NULL)
1079   {
1080     m_stat.aggregate(& event_name_array[m_index]);
1081   }
1082 }
1083 
visit_user(PFS_user * pfs)1084 void PFS_connection_statement_visitor::visit_user(PFS_user *pfs)
1085 {
1086   const PFS_statement_stat *event_name_array;
1087   event_name_array= pfs->read_instr_class_statements_stats();
1088   if (event_name_array != NULL)
1089   {
1090     m_stat.aggregate(& event_name_array[m_index]);
1091   }
1092 }
1093 
visit_account(PFS_account * pfs)1094 void PFS_connection_statement_visitor::visit_account(PFS_account *pfs)
1095 {
1096   const PFS_statement_stat *event_name_array;
1097   event_name_array= pfs->read_instr_class_statements_stats();
1098   if (event_name_array != NULL)
1099   {
1100     m_stat.aggregate(& event_name_array[m_index]);
1101   }
1102 }
1103 
visit_thread(PFS_thread * pfs)1104 void PFS_connection_statement_visitor::visit_thread(PFS_thread *pfs)
1105 {
1106   const PFS_statement_stat *event_name_array;
1107   event_name_array= pfs->read_instr_class_statements_stats();
1108   if (event_name_array != NULL)
1109   {
1110     m_stat.aggregate(& event_name_array[m_index]);
1111   }
1112 }
1113 
1114 /** Instance wait visitor */
1115 PFS_connection_all_statement_visitor
PFS_connection_all_statement_visitor()1116 ::PFS_connection_all_statement_visitor()
1117 {}
1118 
~PFS_connection_all_statement_visitor()1119 PFS_connection_all_statement_visitor::~PFS_connection_all_statement_visitor()
1120 {}
1121 
visit_global()1122 void PFS_connection_all_statement_visitor::visit_global()
1123 {
1124   PFS_statement_stat *stat= global_instr_class_statements_array;
1125   PFS_statement_stat *stat_last= stat + statement_class_max;
1126   for ( ; stat < stat_last; stat++)
1127   {
1128     m_stat.aggregate(stat);
1129   }
1130 }
1131 
visit_connection_slice(PFS_connection_slice * pfs)1132 void PFS_connection_all_statement_visitor::visit_connection_slice(PFS_connection_slice *pfs)
1133 {
1134   const PFS_statement_stat *stat= pfs->read_instr_class_statements_stats();
1135   if (stat != NULL)
1136   {
1137     const PFS_statement_stat *stat_last= stat + statement_class_max;
1138     for ( ; stat < stat_last; stat++)
1139     {
1140       m_stat.aggregate(stat);
1141     }
1142   }
1143 }
1144 
visit_host(PFS_host * pfs)1145 void PFS_connection_all_statement_visitor::visit_host(PFS_host *pfs)
1146 {
1147   visit_connection_slice(pfs);
1148 }
1149 
visit_user(PFS_user * pfs)1150 void PFS_connection_all_statement_visitor::visit_user(PFS_user *pfs)
1151 {
1152   visit_connection_slice(pfs);
1153 }
1154 
visit_account(PFS_account * pfs)1155 void PFS_connection_all_statement_visitor::visit_account(PFS_account *pfs)
1156 {
1157   visit_connection_slice(pfs);
1158 }
1159 
visit_thread(PFS_thread * pfs)1160 void PFS_connection_all_statement_visitor::visit_thread(PFS_thread *pfs)
1161 {
1162   visit_connection_slice(pfs);
1163 }
1164 
1165 PFS_connection_transaction_visitor
PFS_connection_transaction_visitor(PFS_transaction_class * klass)1166 ::PFS_connection_transaction_visitor(PFS_transaction_class *klass)
1167 {
1168   m_index= klass->m_event_name_index;
1169 }
1170 
~PFS_connection_transaction_visitor()1171 PFS_connection_transaction_visitor::~PFS_connection_transaction_visitor()
1172 {}
1173 
visit_global()1174 void PFS_connection_transaction_visitor::visit_global()
1175 {
1176   m_stat.aggregate(&global_transaction_stat);
1177 }
1178 
visit_host(PFS_host * pfs)1179 void PFS_connection_transaction_visitor::visit_host(PFS_host *pfs)
1180 {
1181   const PFS_transaction_stat *event_name_array;
1182   event_name_array= pfs->read_instr_class_transactions_stats();
1183   if (event_name_array != NULL)
1184   {
1185     m_stat.aggregate(& event_name_array[m_index]);
1186   }
1187 }
1188 
visit_user(PFS_user * pfs)1189 void PFS_connection_transaction_visitor::visit_user(PFS_user *pfs)
1190 {
1191   const PFS_transaction_stat *event_name_array;
1192   event_name_array= pfs->read_instr_class_transactions_stats();
1193   if (event_name_array != NULL)
1194   {
1195     m_stat.aggregate(& event_name_array[m_index]);
1196   }
1197 }
1198 
visit_account(PFS_account * pfs)1199 void PFS_connection_transaction_visitor::visit_account(PFS_account *pfs)
1200 {
1201   const PFS_transaction_stat *event_name_array;
1202   event_name_array= pfs->read_instr_class_transactions_stats();
1203   if (event_name_array != NULL)
1204   {
1205     m_stat.aggregate(& event_name_array[m_index]);
1206   }
1207 }
1208 
visit_thread(PFS_thread * pfs)1209 void PFS_connection_transaction_visitor::visit_thread(PFS_thread *pfs)
1210 {
1211   const PFS_transaction_stat *event_name_array;
1212   event_name_array= pfs->read_instr_class_transactions_stats();
1213   if (event_name_array != NULL)
1214   {
1215     m_stat.aggregate(& event_name_array[m_index]);
1216   }
1217 }
1218 
1219 /** Disabled pending code review */
1220 #if 0
1221 /** Instance wait visitor */
1222 PFS_connection_all_transaction_visitor
1223 ::PFS_connection_all_transaction_visitor()
1224 {}
1225 
1226 PFS_connection_all_transaction_visitor::~PFS_connection_all_transaction_visitor()
1227 {}
1228 
1229 void PFS_connection_all_transaction_visitor::visit_global()
1230 {
1231   m_stat.aggregate(&global_transaction_stat);
1232 }
1233 
1234 void PFS_connection_all_transaction_visitor::visit_connection_slice(PFS_connection_slice *pfs)
1235 {
1236   PFS_transaction_stat *stat= pfs->m_instr_class_transactions_stats;
1237   m_stat.aggregate(stat);
1238 }
1239 
1240 void PFS_connection_all_transaction_visitor::visit_host(PFS_host *pfs)
1241 {
1242   visit_connection_slice(pfs);
1243 }
1244 
1245 void PFS_connection_all_transaction_visitor::visit_user(PFS_user *pfs)
1246 {
1247   visit_connection_slice(pfs);
1248 }
1249 
1250 void PFS_connection_all_transaction_visitor::visit_account(PFS_account *pfs)
1251 {
1252   visit_connection_slice(pfs);
1253 }
1254 
1255 void PFS_connection_all_transaction_visitor::visit_thread(PFS_thread *pfs)
1256 {
1257   visit_connection_slice(pfs);
1258 }
1259 #endif
1260 
PFS_connection_stat_visitor()1261 PFS_connection_stat_visitor::PFS_connection_stat_visitor()
1262 {}
1263 
~PFS_connection_stat_visitor()1264 PFS_connection_stat_visitor::~PFS_connection_stat_visitor()
1265 {}
1266 
visit_global()1267 void PFS_connection_stat_visitor::visit_global()
1268 {}
1269 
visit_host(PFS_host * pfs)1270 void PFS_connection_stat_visitor::visit_host(PFS_host *pfs)
1271 {
1272   m_stat.aggregate_disconnected(pfs->m_disconnected_count);
1273 }
1274 
visit_user(PFS_user * pfs)1275 void PFS_connection_stat_visitor::visit_user(PFS_user *pfs)
1276 {
1277   m_stat.aggregate_disconnected(pfs->m_disconnected_count);
1278 }
1279 
visit_account(PFS_account * pfs)1280 void PFS_connection_stat_visitor::visit_account(PFS_account *pfs)
1281 {
1282   m_stat.aggregate_disconnected(pfs->m_disconnected_count);
1283 }
1284 
visit_thread(PFS_thread * pfs)1285 void PFS_connection_stat_visitor::visit_thread(PFS_thread *pfs)
1286 {
1287   /*
1288     PFS_connection_stat_visitor is used in tables accounts,
1289     users and hosts. It should take into account only
1290     FOREGROUND threads.
1291   */
1292   if (pfs->m_processlist_id != 0)
1293     m_stat.aggregate_active(1);
1294 }
1295 
1296 PFS_connection_memory_visitor
PFS_connection_memory_visitor(PFS_memory_class * klass)1297 ::PFS_connection_memory_visitor(PFS_memory_class *klass)
1298 {
1299   m_index= klass->m_event_name_index;
1300   m_stat.reset();
1301 }
1302 
~PFS_connection_memory_visitor()1303 PFS_connection_memory_visitor::~PFS_connection_memory_visitor()
1304 {}
1305 
visit_global()1306 void PFS_connection_memory_visitor::visit_global()
1307 {
1308   PFS_memory_stat *stat;
1309   stat= & global_instr_class_memory_array[m_index];
1310   stat->full_aggregate_to(& m_stat);
1311 }
1312 
visit_host(PFS_host * pfs)1313 void PFS_connection_memory_visitor::visit_host(PFS_host *pfs)
1314 {
1315   const PFS_memory_stat *event_name_array;
1316   event_name_array= pfs->read_instr_class_memory_stats();
1317   if (event_name_array != NULL)
1318   {
1319     const PFS_memory_stat *stat;
1320     stat= & event_name_array[m_index];
1321     stat->full_aggregate_to(& m_stat);
1322   }
1323 }
1324 
visit_user(PFS_user * pfs)1325 void PFS_connection_memory_visitor::visit_user(PFS_user *pfs)
1326 {
1327   const PFS_memory_stat *event_name_array;
1328   event_name_array= pfs->read_instr_class_memory_stats();
1329   if (event_name_array != NULL)
1330   {
1331     const PFS_memory_stat *stat;
1332     stat= & event_name_array[m_index];
1333     stat->full_aggregate_to(& m_stat);
1334   }
1335 }
1336 
visit_account(PFS_account * pfs)1337 void PFS_connection_memory_visitor::visit_account(PFS_account *pfs)
1338 {
1339   const PFS_memory_stat *event_name_array;
1340   event_name_array= pfs->read_instr_class_memory_stats();
1341   if (event_name_array != NULL)
1342   {
1343     const PFS_memory_stat *stat;
1344     stat= & event_name_array[m_index];
1345     stat->full_aggregate_to(& m_stat);
1346   }
1347 }
1348 
visit_thread(PFS_thread * pfs)1349 void PFS_connection_memory_visitor::visit_thread(PFS_thread *pfs)
1350 {
1351   const PFS_memory_stat *event_name_array;
1352   event_name_array= pfs->read_instr_class_memory_stats();
1353   if (event_name_array != NULL)
1354   {
1355     const PFS_memory_stat *stat;
1356     stat= & event_name_array[m_index];
1357     stat->full_aggregate_to(& m_stat);
1358   }
1359 }
1360 
1361 
1362 PFS_connection_status_visitor::
PFS_connection_status_visitor(STATUS_VAR * status_vars)1363 PFS_connection_status_visitor(STATUS_VAR *status_vars) : m_status_vars(status_vars)
1364 {
1365   memset(m_status_vars, 0, sizeof(STATUS_VAR));
1366 }
1367 
~PFS_connection_status_visitor()1368 PFS_connection_status_visitor::~PFS_connection_status_visitor()
1369 {}
1370 
1371 /** Aggregate from global status. */
visit_global()1372 void PFS_connection_status_visitor::visit_global()
1373 {
1374    /* NOTE: Requires lock on LOCK_status. */
1375    mysql_mutex_assert_owner(&LOCK_status);
1376    add_to_status(m_status_vars, &global_status_var, false);
1377 }
1378 
visit_host(PFS_host * pfs)1379 void PFS_connection_status_visitor::visit_host(PFS_host *pfs)
1380 {
1381   pfs->m_status_stats.aggregate_to(m_status_vars);
1382 }
1383 
visit_user(PFS_user * pfs)1384 void PFS_connection_status_visitor::visit_user(PFS_user *pfs)
1385 {
1386   pfs->m_status_stats.aggregate_to(m_status_vars);
1387 }
1388 
visit_account(PFS_account * pfs)1389 void PFS_connection_status_visitor::visit_account(PFS_account *pfs)
1390 {
1391   pfs->m_status_stats.aggregate_to(m_status_vars);
1392 }
1393 
visit_thread(PFS_thread * pfs)1394 void PFS_connection_status_visitor::visit_thread(PFS_thread *pfs)
1395 {
1396 }
1397 
visit_THD(THD * thd)1398 void PFS_connection_status_visitor::visit_THD(THD *thd)
1399 {
1400   if (!thd->status_var_aggregated) {
1401     add_to_status(m_status_vars, &thd->status_var, false);
1402   }
1403 }
1404 
1405 
PFS_instance_wait_visitor()1406 PFS_instance_wait_visitor::PFS_instance_wait_visitor()
1407 {}
1408 
~PFS_instance_wait_visitor()1409 PFS_instance_wait_visitor::~PFS_instance_wait_visitor()
1410 {}
1411 
visit_mutex_class(PFS_mutex_class * pfs)1412 void PFS_instance_wait_visitor::visit_mutex_class(PFS_mutex_class *pfs)
1413 {
1414   m_stat.aggregate(&pfs->m_mutex_stat.m_wait_stat);
1415 }
1416 
visit_rwlock_class(PFS_rwlock_class * pfs)1417 void PFS_instance_wait_visitor::visit_rwlock_class(PFS_rwlock_class *pfs)
1418 {
1419   m_stat.aggregate(&pfs->m_rwlock_stat.m_wait_stat);
1420 }
1421 
visit_cond_class(PFS_cond_class * pfs)1422 void PFS_instance_wait_visitor::visit_cond_class(PFS_cond_class *pfs)
1423 {
1424   m_stat.aggregate(&pfs->m_cond_stat.m_wait_stat);
1425 }
1426 
visit_file_class(PFS_file_class * pfs)1427 void PFS_instance_wait_visitor::visit_file_class(PFS_file_class *pfs)
1428 {
1429   pfs->m_file_stat.m_io_stat.sum_waits(&m_stat);
1430 }
1431 
visit_socket_class(PFS_socket_class * pfs)1432 void PFS_instance_wait_visitor::visit_socket_class(PFS_socket_class *pfs)
1433 {
1434   pfs->m_socket_stat.m_io_stat.sum_waits(&m_stat);
1435 }
1436 
visit_mutex(PFS_mutex * pfs)1437 void PFS_instance_wait_visitor::visit_mutex(PFS_mutex *pfs)
1438 {
1439   m_stat.aggregate(& pfs->m_mutex_stat.m_wait_stat);
1440 }
1441 
visit_rwlock(PFS_rwlock * pfs)1442 void PFS_instance_wait_visitor::visit_rwlock(PFS_rwlock *pfs)
1443 {
1444   m_stat.aggregate(& pfs->m_rwlock_stat.m_wait_stat);
1445 }
1446 
visit_cond(PFS_cond * pfs)1447 void PFS_instance_wait_visitor::visit_cond(PFS_cond *pfs)
1448 {
1449   m_stat.aggregate(& pfs->m_cond_stat.m_wait_stat);
1450 }
1451 
visit_file(PFS_file * pfs)1452 void PFS_instance_wait_visitor::visit_file(PFS_file *pfs)
1453 {
1454   /* Combine per-operation file wait stats before aggregating */
1455   PFS_single_stat stat;
1456   pfs->m_file_stat.m_io_stat.sum_waits(&stat);
1457   m_stat.aggregate(&stat);
1458 }
1459 
visit_socket(PFS_socket * pfs)1460 void PFS_instance_wait_visitor::visit_socket(PFS_socket *pfs)
1461 {
1462   /* Combine per-operation socket wait stats before aggregating */
1463   PFS_single_stat stat;
1464   pfs->m_socket_stat.m_io_stat.sum_waits(&stat);
1465   m_stat.aggregate(&stat);
1466 }
1467 
1468 /** Table IO wait visitor */
1469 
PFS_object_wait_visitor()1470 PFS_object_wait_visitor::PFS_object_wait_visitor()
1471 {}
1472 
~PFS_object_wait_visitor()1473 PFS_object_wait_visitor::~PFS_object_wait_visitor()
1474 {}
1475 
visit_global()1476 void PFS_object_wait_visitor::visit_global()
1477 {
1478   global_table_io_stat.sum(& m_stat);
1479   global_table_lock_stat.sum(& m_stat);
1480 }
1481 
visit_table_share(PFS_table_share * pfs)1482 void PFS_object_wait_visitor::visit_table_share(PFS_table_share *pfs)
1483 {
1484   uint safe_key_count= sanitize_index_count(pfs->m_key_count);
1485   pfs->sum(& m_stat, safe_key_count);
1486 }
1487 
visit_table(PFS_table * pfs)1488 void PFS_object_wait_visitor::visit_table(PFS_table *pfs)
1489 {
1490   PFS_table_share *table_share= sanitize_table_share(pfs->m_share);
1491   if (table_share != NULL)
1492   {
1493     uint safe_key_count= sanitize_index_count(table_share->m_key_count);
1494     pfs->m_table_stat.sum(& m_stat, safe_key_count);
1495   }
1496 }
1497 
PFS_table_io_wait_visitor()1498 PFS_table_io_wait_visitor::PFS_table_io_wait_visitor()
1499 {}
1500 
~PFS_table_io_wait_visitor()1501 PFS_table_io_wait_visitor::~PFS_table_io_wait_visitor()
1502 {}
1503 
visit_global()1504 void PFS_table_io_wait_visitor::visit_global()
1505 {
1506   global_table_io_stat.sum(& m_stat);
1507 }
1508 
visit_table_share(PFS_table_share * pfs)1509 void PFS_table_io_wait_visitor::visit_table_share(PFS_table_share *pfs)
1510 {
1511   PFS_table_io_stat io_stat;
1512   uint safe_key_count= sanitize_index_count(pfs->m_key_count);
1513   uint index;
1514   PFS_table_share_index *index_stat;
1515 
1516   /* Aggregate index stats */
1517   for (index= 0; index < safe_key_count; index++)
1518   {
1519     index_stat= pfs->find_index_stat(index);
1520     if (index_stat != NULL)
1521       io_stat.aggregate(& index_stat->m_stat);
1522   }
1523 
1524   /* Aggregate global stats */
1525   index_stat= pfs->find_index_stat(MAX_INDEXES);
1526   if (index_stat != NULL)
1527     io_stat.aggregate(& index_stat->m_stat);
1528 
1529   io_stat.sum(& m_stat);
1530 }
1531 
visit_table(PFS_table * pfs)1532 void PFS_table_io_wait_visitor::visit_table(PFS_table *pfs)
1533 {
1534   PFS_table_share *safe_share= sanitize_table_share(pfs->m_share);
1535 
1536   if (likely(safe_share != NULL))
1537   {
1538     PFS_table_io_stat io_stat;
1539     uint safe_key_count= sanitize_index_count(safe_share->m_key_count);
1540     uint index;
1541 
1542     /* Aggregate index stats */
1543     for (index= 0; index < safe_key_count; index++)
1544       io_stat.aggregate(& pfs->m_table_stat.m_index_stat[index]);
1545 
1546     /* Aggregate global stats */
1547     io_stat.aggregate(& pfs->m_table_stat.m_index_stat[MAX_INDEXES]);
1548 
1549     io_stat.sum(& m_stat);
1550   }
1551 }
1552 
1553 /** Table IO stat visitor */
1554 
PFS_table_io_stat_visitor()1555 PFS_table_io_stat_visitor::PFS_table_io_stat_visitor()
1556 {}
1557 
~PFS_table_io_stat_visitor()1558 PFS_table_io_stat_visitor::~PFS_table_io_stat_visitor()
1559 {}
1560 
visit_table_share(PFS_table_share * pfs)1561 void PFS_table_io_stat_visitor::visit_table_share(PFS_table_share *pfs)
1562 {
1563   uint safe_key_count= sanitize_index_count(pfs->m_key_count);
1564   uint index;
1565   PFS_table_share_index *index_stat;
1566 
1567   /* Aggregate index stats */
1568   for (index= 0; index < safe_key_count; index++)
1569   {
1570     index_stat= pfs->find_index_stat(index);
1571     if (index_stat != NULL)
1572       m_stat.aggregate(& index_stat->m_stat);
1573   }
1574 
1575   /* Aggregate global stats */
1576   index_stat= pfs->find_index_stat(MAX_INDEXES);
1577   if (index_stat != NULL)
1578     m_stat.aggregate(& index_stat->m_stat);
1579 }
1580 
visit_table(PFS_table * pfs)1581 void PFS_table_io_stat_visitor::visit_table(PFS_table *pfs)
1582 {
1583   PFS_table_share *safe_share= sanitize_table_share(pfs->m_share);
1584 
1585   if (likely(safe_share != NULL))
1586   {
1587     uint safe_key_count= sanitize_index_count(safe_share->m_key_count);
1588     uint index;
1589 
1590     /* Aggregate index stats */
1591     for (index= 0; index < safe_key_count; index++)
1592       m_stat.aggregate(& pfs->m_table_stat.m_index_stat[index]);
1593 
1594     /* Aggregate global stats */
1595     m_stat.aggregate(& pfs->m_table_stat.m_index_stat[MAX_INDEXES]);
1596   }
1597 }
1598 
1599 /** Index IO stat visitor */
1600 
PFS_index_io_stat_visitor()1601 PFS_index_io_stat_visitor::PFS_index_io_stat_visitor()
1602 {}
1603 
~PFS_index_io_stat_visitor()1604 PFS_index_io_stat_visitor::~PFS_index_io_stat_visitor()
1605 {}
1606 
visit_table_share_index(PFS_table_share * pfs,uint index)1607 void PFS_index_io_stat_visitor::visit_table_share_index(PFS_table_share *pfs, uint index)
1608 {
1609   PFS_table_share_index *index_stat;
1610 
1611   index_stat= pfs->find_index_stat(index);
1612   if (index_stat != NULL)
1613     m_stat.aggregate(& index_stat->m_stat);
1614 }
1615 
visit_table_index(PFS_table * pfs,uint index)1616 void PFS_index_io_stat_visitor::visit_table_index(PFS_table *pfs, uint index)
1617 {
1618   m_stat.aggregate(& pfs->m_table_stat.m_index_stat[index]);
1619 }
1620 
1621 /** Table lock wait visitor */
1622 
PFS_table_lock_wait_visitor()1623 PFS_table_lock_wait_visitor::PFS_table_lock_wait_visitor()
1624 {}
1625 
~PFS_table_lock_wait_visitor()1626 PFS_table_lock_wait_visitor::~PFS_table_lock_wait_visitor()
1627 {}
1628 
visit_global()1629 void PFS_table_lock_wait_visitor::visit_global()
1630 {
1631   global_table_lock_stat.sum(& m_stat);
1632 }
1633 
visit_table_share(PFS_table_share * pfs)1634 void PFS_table_lock_wait_visitor::visit_table_share(PFS_table_share *pfs)
1635 {
1636   pfs->sum_lock(& m_stat);
1637 }
1638 
visit_table(PFS_table * pfs)1639 void PFS_table_lock_wait_visitor::visit_table(PFS_table *pfs)
1640 {
1641   pfs->m_table_stat.sum_lock(& m_stat);
1642 }
1643 
1644 /** Table lock stat visitor */
1645 
PFS_table_lock_stat_visitor()1646 PFS_table_lock_stat_visitor::PFS_table_lock_stat_visitor()
1647 {}
1648 
~PFS_table_lock_stat_visitor()1649 PFS_table_lock_stat_visitor::~PFS_table_lock_stat_visitor()
1650 {}
1651 
visit_table_share(PFS_table_share * pfs)1652 void PFS_table_lock_stat_visitor::visit_table_share(PFS_table_share *pfs)
1653 {
1654   PFS_table_share_lock *lock_stat;
1655 
1656   lock_stat= pfs->find_lock_stat();
1657   if (lock_stat != NULL)
1658     m_stat.aggregate(& lock_stat->m_stat);
1659 }
1660 
visit_table(PFS_table * pfs)1661 void PFS_table_lock_stat_visitor::visit_table(PFS_table *pfs)
1662 {
1663   m_stat.aggregate(& pfs->m_table_stat.m_lock_stat);
1664 }
1665 
PFS_instance_socket_io_stat_visitor()1666 PFS_instance_socket_io_stat_visitor::PFS_instance_socket_io_stat_visitor()
1667 {}
1668 
~PFS_instance_socket_io_stat_visitor()1669 PFS_instance_socket_io_stat_visitor::~PFS_instance_socket_io_stat_visitor()
1670 {}
1671 
visit_socket_class(PFS_socket_class * pfs)1672 void PFS_instance_socket_io_stat_visitor::visit_socket_class(PFS_socket_class *pfs)
1673 {
1674   /* Aggregate wait times, event counts and byte counts */
1675   m_socket_io_stat.aggregate(&pfs->m_socket_stat.m_io_stat);
1676 }
1677 
visit_socket(PFS_socket * pfs)1678 void PFS_instance_socket_io_stat_visitor::visit_socket(PFS_socket *pfs)
1679 {
1680   /* Aggregate wait times, event counts and byte counts */
1681   m_socket_io_stat.aggregate(&pfs->m_socket_stat.m_io_stat);
1682 }
1683 
PFS_instance_file_io_stat_visitor()1684 PFS_instance_file_io_stat_visitor::PFS_instance_file_io_stat_visitor()
1685 {}
1686 
~PFS_instance_file_io_stat_visitor()1687 PFS_instance_file_io_stat_visitor::~PFS_instance_file_io_stat_visitor()
1688 {}
1689 
visit_file_class(PFS_file_class * pfs)1690 void PFS_instance_file_io_stat_visitor::visit_file_class(PFS_file_class *pfs)
1691 {
1692   /* Aggregate wait times, event counts and byte counts */
1693   m_file_io_stat.aggregate(&pfs->m_file_stat.m_io_stat);
1694 }
1695 
visit_file(PFS_file * pfs)1696 void PFS_instance_file_io_stat_visitor::visit_file(PFS_file *pfs)
1697 {
1698   /* Aggregate wait times, event counts and byte counts */
1699   m_file_io_stat.aggregate(&pfs->m_file_stat.m_io_stat);
1700 }
1701 /** @} */
1702