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 *)1285 void PFS_connection_stat_visitor::visit_thread(PFS_thread *)
1286 {
1287   m_stat.aggregate_active(1);
1288 }
1289 
1290 PFS_connection_memory_visitor
PFS_connection_memory_visitor(PFS_memory_class * klass)1291 ::PFS_connection_memory_visitor(PFS_memory_class *klass)
1292 {
1293   m_index= klass->m_event_name_index;
1294   m_stat.reset();
1295 }
1296 
~PFS_connection_memory_visitor()1297 PFS_connection_memory_visitor::~PFS_connection_memory_visitor()
1298 {}
1299 
visit_global()1300 void PFS_connection_memory_visitor::visit_global()
1301 {
1302   PFS_memory_stat *stat;
1303   stat= & global_instr_class_memory_array[m_index];
1304   stat->full_aggregate_to(& m_stat);
1305 }
1306 
visit_host(PFS_host * pfs)1307 void PFS_connection_memory_visitor::visit_host(PFS_host *pfs)
1308 {
1309   const PFS_memory_stat *event_name_array;
1310   event_name_array= pfs->read_instr_class_memory_stats();
1311   if (event_name_array != NULL)
1312   {
1313     const PFS_memory_stat *stat;
1314     stat= & event_name_array[m_index];
1315     stat->full_aggregate_to(& m_stat);
1316   }
1317 }
1318 
visit_user(PFS_user * pfs)1319 void PFS_connection_memory_visitor::visit_user(PFS_user *pfs)
1320 {
1321   const PFS_memory_stat *event_name_array;
1322   event_name_array= pfs->read_instr_class_memory_stats();
1323   if (event_name_array != NULL)
1324   {
1325     const PFS_memory_stat *stat;
1326     stat= & event_name_array[m_index];
1327     stat->full_aggregate_to(& m_stat);
1328   }
1329 }
1330 
visit_account(PFS_account * pfs)1331 void PFS_connection_memory_visitor::visit_account(PFS_account *pfs)
1332 {
1333   const PFS_memory_stat *event_name_array;
1334   event_name_array= pfs->read_instr_class_memory_stats();
1335   if (event_name_array != NULL)
1336   {
1337     const PFS_memory_stat *stat;
1338     stat= & event_name_array[m_index];
1339     stat->full_aggregate_to(& m_stat);
1340   }
1341 }
1342 
visit_thread(PFS_thread * pfs)1343 void PFS_connection_memory_visitor::visit_thread(PFS_thread *pfs)
1344 {
1345   const PFS_memory_stat *event_name_array;
1346   event_name_array= pfs->read_instr_class_memory_stats();
1347   if (event_name_array != NULL)
1348   {
1349     const PFS_memory_stat *stat;
1350     stat= & event_name_array[m_index];
1351     stat->full_aggregate_to(& m_stat);
1352   }
1353 }
1354 
1355 
1356 PFS_connection_status_visitor::
PFS_connection_status_visitor(STATUS_VAR * status_vars)1357 PFS_connection_status_visitor(STATUS_VAR *status_vars) : m_status_vars(status_vars)
1358 {
1359   memset(m_status_vars, 0, sizeof(STATUS_VAR));
1360 }
1361 
~PFS_connection_status_visitor()1362 PFS_connection_status_visitor::~PFS_connection_status_visitor()
1363 {}
1364 
1365 /** Aggregate from global status. */
visit_global()1366 void PFS_connection_status_visitor::visit_global()
1367 {
1368    /* NOTE: Requires lock on LOCK_status. */
1369    mysql_mutex_assert_owner(&LOCK_status);
1370    add_to_status(m_status_vars, &global_status_var, false);
1371 }
1372 
visit_host(PFS_host * pfs)1373 void PFS_connection_status_visitor::visit_host(PFS_host *pfs)
1374 {
1375   pfs->m_status_stats.aggregate_to(m_status_vars);
1376 }
1377 
visit_user(PFS_user * pfs)1378 void PFS_connection_status_visitor::visit_user(PFS_user *pfs)
1379 {
1380   pfs->m_status_stats.aggregate_to(m_status_vars);
1381 }
1382 
visit_account(PFS_account * pfs)1383 void PFS_connection_status_visitor::visit_account(PFS_account *pfs)
1384 {
1385   pfs->m_status_stats.aggregate_to(m_status_vars);
1386 }
1387 
visit_thread(PFS_thread * pfs)1388 void PFS_connection_status_visitor::visit_thread(PFS_thread *pfs)
1389 {
1390 }
1391 
visit_THD(THD * thd)1392 void PFS_connection_status_visitor::visit_THD(THD *thd)
1393 {
1394   add_to_status(m_status_vars, &thd->status_var, false);
1395 }
1396 
1397 
PFS_instance_wait_visitor()1398 PFS_instance_wait_visitor::PFS_instance_wait_visitor()
1399 {}
1400 
~PFS_instance_wait_visitor()1401 PFS_instance_wait_visitor::~PFS_instance_wait_visitor()
1402 {}
1403 
visit_mutex_class(PFS_mutex_class * pfs)1404 void PFS_instance_wait_visitor::visit_mutex_class(PFS_mutex_class *pfs)
1405 {
1406   m_stat.aggregate(&pfs->m_mutex_stat.m_wait_stat);
1407 }
1408 
visit_rwlock_class(PFS_rwlock_class * pfs)1409 void PFS_instance_wait_visitor::visit_rwlock_class(PFS_rwlock_class *pfs)
1410 {
1411   m_stat.aggregate(&pfs->m_rwlock_stat.m_wait_stat);
1412 }
1413 
visit_cond_class(PFS_cond_class * pfs)1414 void PFS_instance_wait_visitor::visit_cond_class(PFS_cond_class *pfs)
1415 {
1416   m_stat.aggregate(&pfs->m_cond_stat.m_wait_stat);
1417 }
1418 
visit_file_class(PFS_file_class * pfs)1419 void PFS_instance_wait_visitor::visit_file_class(PFS_file_class *pfs)
1420 {
1421   pfs->m_file_stat.m_io_stat.sum_waits(&m_stat);
1422 }
1423 
visit_socket_class(PFS_socket_class * pfs)1424 void PFS_instance_wait_visitor::visit_socket_class(PFS_socket_class *pfs)
1425 {
1426   pfs->m_socket_stat.m_io_stat.sum_waits(&m_stat);
1427 }
1428 
visit_mutex(PFS_mutex * pfs)1429 void PFS_instance_wait_visitor::visit_mutex(PFS_mutex *pfs)
1430 {
1431   m_stat.aggregate(& pfs->m_mutex_stat.m_wait_stat);
1432 }
1433 
visit_rwlock(PFS_rwlock * pfs)1434 void PFS_instance_wait_visitor::visit_rwlock(PFS_rwlock *pfs)
1435 {
1436   m_stat.aggregate(& pfs->m_rwlock_stat.m_wait_stat);
1437 }
1438 
visit_cond(PFS_cond * pfs)1439 void PFS_instance_wait_visitor::visit_cond(PFS_cond *pfs)
1440 {
1441   m_stat.aggregate(& pfs->m_cond_stat.m_wait_stat);
1442 }
1443 
visit_file(PFS_file * pfs)1444 void PFS_instance_wait_visitor::visit_file(PFS_file *pfs)
1445 {
1446   /* Combine per-operation file wait stats before aggregating */
1447   PFS_single_stat stat;
1448   pfs->m_file_stat.m_io_stat.sum_waits(&stat);
1449   m_stat.aggregate(&stat);
1450 }
1451 
visit_socket(PFS_socket * pfs)1452 void PFS_instance_wait_visitor::visit_socket(PFS_socket *pfs)
1453 {
1454   /* Combine per-operation socket wait stats before aggregating */
1455   PFS_single_stat stat;
1456   pfs->m_socket_stat.m_io_stat.sum_waits(&stat);
1457   m_stat.aggregate(&stat);
1458 }
1459 
1460 /** Table IO wait visitor */
1461 
PFS_object_wait_visitor()1462 PFS_object_wait_visitor::PFS_object_wait_visitor()
1463 {}
1464 
~PFS_object_wait_visitor()1465 PFS_object_wait_visitor::~PFS_object_wait_visitor()
1466 {}
1467 
visit_global()1468 void PFS_object_wait_visitor::visit_global()
1469 {
1470   global_table_io_stat.sum(& m_stat);
1471   global_table_lock_stat.sum(& m_stat);
1472 }
1473 
visit_table_share(PFS_table_share * pfs)1474 void PFS_object_wait_visitor::visit_table_share(PFS_table_share *pfs)
1475 {
1476   uint safe_key_count= sanitize_index_count(pfs->m_key_count);
1477   pfs->sum(& m_stat, safe_key_count);
1478 }
1479 
visit_table(PFS_table * pfs)1480 void PFS_object_wait_visitor::visit_table(PFS_table *pfs)
1481 {
1482   PFS_table_share *table_share= sanitize_table_share(pfs->m_share);
1483   if (table_share != NULL)
1484   {
1485     uint safe_key_count= sanitize_index_count(table_share->m_key_count);
1486     pfs->m_table_stat.sum(& m_stat, safe_key_count);
1487   }
1488 }
1489 
PFS_table_io_wait_visitor()1490 PFS_table_io_wait_visitor::PFS_table_io_wait_visitor()
1491 {}
1492 
~PFS_table_io_wait_visitor()1493 PFS_table_io_wait_visitor::~PFS_table_io_wait_visitor()
1494 {}
1495 
visit_global()1496 void PFS_table_io_wait_visitor::visit_global()
1497 {
1498   global_table_io_stat.sum(& m_stat);
1499 }
1500 
visit_table_share(PFS_table_share * pfs)1501 void PFS_table_io_wait_visitor::visit_table_share(PFS_table_share *pfs)
1502 {
1503   PFS_table_io_stat io_stat;
1504   uint safe_key_count= sanitize_index_count(pfs->m_key_count);
1505   uint index;
1506   PFS_table_share_index *index_stat;
1507 
1508   /* Aggregate index stats */
1509   for (index= 0; index < safe_key_count; index++)
1510   {
1511     index_stat= pfs->find_index_stat(index);
1512     if (index_stat != NULL)
1513       io_stat.aggregate(& index_stat->m_stat);
1514   }
1515 
1516   /* Aggregate global stats */
1517   index_stat= pfs->find_index_stat(MAX_INDEXES);
1518   if (index_stat != NULL)
1519     io_stat.aggregate(& index_stat->m_stat);
1520 
1521   io_stat.sum(& m_stat);
1522 }
1523 
visit_table(PFS_table * pfs)1524 void PFS_table_io_wait_visitor::visit_table(PFS_table *pfs)
1525 {
1526   PFS_table_share *safe_share= sanitize_table_share(pfs->m_share);
1527 
1528   if (likely(safe_share != NULL))
1529   {
1530     PFS_table_io_stat io_stat;
1531     uint safe_key_count= sanitize_index_count(safe_share->m_key_count);
1532     uint index;
1533 
1534     /* Aggregate index stats */
1535     for (index= 0; index < safe_key_count; index++)
1536       io_stat.aggregate(& pfs->m_table_stat.m_index_stat[index]);
1537 
1538     /* Aggregate global stats */
1539     io_stat.aggregate(& pfs->m_table_stat.m_index_stat[MAX_INDEXES]);
1540 
1541     io_stat.sum(& m_stat);
1542   }
1543 }
1544 
1545 /** Table IO stat visitor */
1546 
PFS_table_io_stat_visitor()1547 PFS_table_io_stat_visitor::PFS_table_io_stat_visitor()
1548 {}
1549 
~PFS_table_io_stat_visitor()1550 PFS_table_io_stat_visitor::~PFS_table_io_stat_visitor()
1551 {}
1552 
visit_table_share(PFS_table_share * pfs)1553 void PFS_table_io_stat_visitor::visit_table_share(PFS_table_share *pfs)
1554 {
1555   uint safe_key_count= sanitize_index_count(pfs->m_key_count);
1556   uint index;
1557   PFS_table_share_index *index_stat;
1558 
1559   /* Aggregate index stats */
1560   for (index= 0; index < safe_key_count; index++)
1561   {
1562     index_stat= pfs->find_index_stat(index);
1563     if (index_stat != NULL)
1564       m_stat.aggregate(& index_stat->m_stat);
1565   }
1566 
1567   /* Aggregate global stats */
1568   index_stat= pfs->find_index_stat(MAX_INDEXES);
1569   if (index_stat != NULL)
1570     m_stat.aggregate(& index_stat->m_stat);
1571 }
1572 
visit_table(PFS_table * pfs)1573 void PFS_table_io_stat_visitor::visit_table(PFS_table *pfs)
1574 {
1575   PFS_table_share *safe_share= sanitize_table_share(pfs->m_share);
1576 
1577   if (likely(safe_share != NULL))
1578   {
1579     uint safe_key_count= sanitize_index_count(safe_share->m_key_count);
1580     uint index;
1581 
1582     /* Aggregate index stats */
1583     for (index= 0; index < safe_key_count; index++)
1584       m_stat.aggregate(& pfs->m_table_stat.m_index_stat[index]);
1585 
1586     /* Aggregate global stats */
1587     m_stat.aggregate(& pfs->m_table_stat.m_index_stat[MAX_INDEXES]);
1588   }
1589 }
1590 
1591 /** Index IO stat visitor */
1592 
PFS_index_io_stat_visitor()1593 PFS_index_io_stat_visitor::PFS_index_io_stat_visitor()
1594 {}
1595 
~PFS_index_io_stat_visitor()1596 PFS_index_io_stat_visitor::~PFS_index_io_stat_visitor()
1597 {}
1598 
visit_table_share_index(PFS_table_share * pfs,uint index)1599 void PFS_index_io_stat_visitor::visit_table_share_index(PFS_table_share *pfs, uint index)
1600 {
1601   PFS_table_share_index *index_stat;
1602 
1603   index_stat= pfs->find_index_stat(index);
1604   if (index_stat != NULL)
1605     m_stat.aggregate(& index_stat->m_stat);
1606 }
1607 
visit_table_index(PFS_table * pfs,uint index)1608 void PFS_index_io_stat_visitor::visit_table_index(PFS_table *pfs, uint index)
1609 {
1610   m_stat.aggregate(& pfs->m_table_stat.m_index_stat[index]);
1611 }
1612 
1613 /** Table lock wait visitor */
1614 
PFS_table_lock_wait_visitor()1615 PFS_table_lock_wait_visitor::PFS_table_lock_wait_visitor()
1616 {}
1617 
~PFS_table_lock_wait_visitor()1618 PFS_table_lock_wait_visitor::~PFS_table_lock_wait_visitor()
1619 {}
1620 
visit_global()1621 void PFS_table_lock_wait_visitor::visit_global()
1622 {
1623   global_table_lock_stat.sum(& m_stat);
1624 }
1625 
visit_table_share(PFS_table_share * pfs)1626 void PFS_table_lock_wait_visitor::visit_table_share(PFS_table_share *pfs)
1627 {
1628   pfs->sum_lock(& m_stat);
1629 }
1630 
visit_table(PFS_table * pfs)1631 void PFS_table_lock_wait_visitor::visit_table(PFS_table *pfs)
1632 {
1633   pfs->m_table_stat.sum_lock(& m_stat);
1634 }
1635 
1636 /** Table lock stat visitor */
1637 
PFS_table_lock_stat_visitor()1638 PFS_table_lock_stat_visitor::PFS_table_lock_stat_visitor()
1639 {}
1640 
~PFS_table_lock_stat_visitor()1641 PFS_table_lock_stat_visitor::~PFS_table_lock_stat_visitor()
1642 {}
1643 
visit_table_share(PFS_table_share * pfs)1644 void PFS_table_lock_stat_visitor::visit_table_share(PFS_table_share *pfs)
1645 {
1646   PFS_table_share_lock *lock_stat;
1647 
1648   lock_stat= pfs->find_lock_stat();
1649   if (lock_stat != NULL)
1650     m_stat.aggregate(& lock_stat->m_stat);
1651 }
1652 
visit_table(PFS_table * pfs)1653 void PFS_table_lock_stat_visitor::visit_table(PFS_table *pfs)
1654 {
1655   m_stat.aggregate(& pfs->m_table_stat.m_lock_stat);
1656 }
1657 
PFS_instance_socket_io_stat_visitor()1658 PFS_instance_socket_io_stat_visitor::PFS_instance_socket_io_stat_visitor()
1659 {}
1660 
~PFS_instance_socket_io_stat_visitor()1661 PFS_instance_socket_io_stat_visitor::~PFS_instance_socket_io_stat_visitor()
1662 {}
1663 
visit_socket_class(PFS_socket_class * pfs)1664 void PFS_instance_socket_io_stat_visitor::visit_socket_class(PFS_socket_class *pfs)
1665 {
1666   /* Aggregate wait times, event counts and byte counts */
1667   m_socket_io_stat.aggregate(&pfs->m_socket_stat.m_io_stat);
1668 }
1669 
visit_socket(PFS_socket * pfs)1670 void PFS_instance_socket_io_stat_visitor::visit_socket(PFS_socket *pfs)
1671 {
1672   /* Aggregate wait times, event counts and byte counts */
1673   m_socket_io_stat.aggregate(&pfs->m_socket_stat.m_io_stat);
1674 }
1675 
PFS_instance_file_io_stat_visitor()1676 PFS_instance_file_io_stat_visitor::PFS_instance_file_io_stat_visitor()
1677 {}
1678 
~PFS_instance_file_io_stat_visitor()1679 PFS_instance_file_io_stat_visitor::~PFS_instance_file_io_stat_visitor()
1680 {}
1681 
visit_file_class(PFS_file_class * pfs)1682 void PFS_instance_file_io_stat_visitor::visit_file_class(PFS_file_class *pfs)
1683 {
1684   /* Aggregate wait times, event counts and byte counts */
1685   m_file_io_stat.aggregate(&pfs->m_file_stat.m_io_stat);
1686 }
1687 
visit_file(PFS_file * pfs)1688 void PFS_instance_file_io_stat_visitor::visit_file(PFS_file *pfs)
1689 {
1690   /* Aggregate wait times, event counts and byte counts */
1691   m_file_io_stat.aggregate(&pfs->m_file_stat.m_io_stat);
1692 }
1693 /** @} */
1694