|
1 | 1 | /*
|
2 |
| - * Copyright (c) 1998, 2021, Oracle and/or its affiliates. All rights reserved. |
| 2 | + * Copyright (c) 1998, 2022, Oracle and/or its affiliates. All rights reserved. |
3 | 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
4 | 4 | *
|
5 | 5 | * This code is free software; you can redistribute it and/or modify it
|
@@ -534,6 +534,62 @@ synthesizeUnloadEvent(void *signatureVoid, void *envVoid)
|
534 | 534 | /* Garbage Collection Happened */
|
535 | 535 | static unsigned int garbageCollected = 0;
|
536 | 536 |
|
| 537 | +/* |
| 538 | + * Run the event through each HandlerNode's filter, and if it passes, call the HandlerNode's |
| 539 | + * HandlerFunction for the event, and then report all accumulated events to the debugger. |
| 540 | + */ |
| 541 | +static void |
| 542 | +filterAndHandleEvent(JNIEnv *env, EventInfo *evinfo, EventIndex ei, |
| 543 | + struct bag *eventBag, jbyte eventSessionID) |
| 544 | +{ |
| 545 | + debugMonitorEnter(handlerLock); |
| 546 | + { |
| 547 | + HandlerNode *node; |
| 548 | + char *classname; |
| 549 | + |
| 550 | + /* We must keep track of all classes prepared to know what's unloaded */ |
| 551 | + if (evinfo->ei == EI_CLASS_PREPARE) { |
| 552 | + classTrack_addPreparedClass(env, evinfo->clazz); |
| 553 | + } |
| 554 | + |
| 555 | + node = getHandlerChain(ei)->first; |
| 556 | + classname = getClassname(evinfo->clazz); |
| 557 | + |
| 558 | + /* Filter the event over each handler node. */ |
| 559 | + while (node != NULL) { |
| 560 | + /* Save next so handlers can remove themselves. */ |
| 561 | + HandlerNode *next = NEXT(node); |
| 562 | + jboolean shouldDelete; |
| 563 | + |
| 564 | + if (eventFilterRestricted_passesFilter(env, classname, |
| 565 | + evinfo, node, |
| 566 | + &shouldDelete)) { |
| 567 | + HandlerFunction func = HANDLER_FUNCTION(node); |
| 568 | + if (func == NULL) { |
| 569 | + EXIT_ERROR(AGENT_ERROR_INTERNAL,"handler function NULL"); |
| 570 | + } |
| 571 | + /* Handle the event by calling the event handler. */ |
| 572 | + (*func)(env, evinfo, node, eventBag); |
| 573 | + } |
| 574 | + if (shouldDelete) { |
| 575 | + /* We can safely free the node now that we are done using it. */ |
| 576 | + (void)freeHandler(node); |
| 577 | + } |
| 578 | + node = next; |
| 579 | + } |
| 580 | + jvmtiDeallocate(classname); |
| 581 | + } |
| 582 | + debugMonitorExit(handlerLock); |
| 583 | + |
| 584 | + /* |
| 585 | + * The events destined for the debugger were accumulated in eventBag. Report all these events. |
| 586 | + */ |
| 587 | + if (eventBag != NULL) { |
| 588 | + reportEvents(env, eventSessionID, evinfo->thread, evinfo->ei, |
| 589 | + evinfo->clazz, evinfo->method, evinfo->location, eventBag); |
| 590 | + } |
| 591 | +} |
| 592 | + |
537 | 593 | /*
|
538 | 594 | * The JVMTI generic event callback. Each event is passed to a sequence of
|
539 | 595 | * handlers in a chain until the chain ends or one handler
|
@@ -634,51 +690,7 @@ event_callback(JNIEnv *env, EventInfo *evinfo)
|
634 | 690 | }
|
635 | 691 | }
|
636 | 692 |
|
637 |
| - debugMonitorEnter(handlerLock); |
638 |
| - { |
639 |
| - HandlerNode *node; |
640 |
| - char *classname; |
641 |
| - |
642 |
| - /* We must keep track of all classes prepared to know what's unloaded */ |
643 |
| - if (evinfo->ei == EI_CLASS_PREPARE) { |
644 |
| - classTrack_addPreparedClass(env, evinfo->clazz); |
645 |
| - } |
646 |
| - |
647 |
| - node = getHandlerChain(evinfo->ei)->first; |
648 |
| - classname = getClassname(evinfo->clazz); |
649 |
| - |
650 |
| - while (node != NULL) { |
651 |
| - /* save next so handlers can remove themselves */ |
652 |
| - HandlerNode *next = NEXT(node); |
653 |
| - jboolean shouldDelete; |
654 |
| - |
655 |
| - if (eventFilterRestricted_passesFilter(env, classname, |
656 |
| - evinfo, node, |
657 |
| - &shouldDelete)) { |
658 |
| - HandlerFunction func; |
659 |
| - |
660 |
| - func = HANDLER_FUNCTION(node); |
661 |
| - if ( func == NULL ) { |
662 |
| - EXIT_ERROR(AGENT_ERROR_INTERNAL,"handler function NULL"); |
663 |
| - } |
664 |
| - (*func)(env, evinfo, node, eventBag); |
665 |
| - } |
666 |
| - if (shouldDelete) { |
667 |
| - /* We can safely free the node now that we are done |
668 |
| - * using it. |
669 |
| - */ |
670 |
| - (void)freeHandler(node); |
671 |
| - } |
672 |
| - node = next; |
673 |
| - } |
674 |
| - jvmtiDeallocate(classname); |
675 |
| - } |
676 |
| - debugMonitorExit(handlerLock); |
677 |
| - |
678 |
| - if (eventBag != NULL) { |
679 |
| - reportEvents(env, eventSessionID, thread, evinfo->ei, |
680 |
| - evinfo->clazz, evinfo->method, evinfo->location, eventBag); |
681 |
| - } |
| 693 | + filterAndHandleEvent(env, evinfo, ei, eventBag, eventSessionID); |
682 | 694 |
|
683 | 695 | /* we are continuing after VMDeathEvent - now we are dead */
|
684 | 696 | if (evinfo->ei == EI_VM_DEATH) {
|
|
0 commit comments