Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [aspectj-users] if and loop pointcuts

Diana Szentivanyi wrote:
<snip>
> the "take lock" advice
> code should be weaved in before only the first access,
> and the "release lock" advice code should be weaved in
> after only the last access.
<snip>
>  --- Gregor Kiczales <gregor@xxxxxxxxx> wrote: >
>>Before thinking about this more, I want to ask why
>> you don't want to do
>>the simpler thing of just releasing the lock when the
>> enclosing method
>>terminates?

I believe Gregor asked about the method because it's
easy to detect when it is finishing executing.  To detect
the "last" access to the variable would require knowing
everything about the code that could run between a
given access and the end of the method.  So if you relax
the requirement to permit releasing the lock when
exiting the scope, it can be done in AspectJ.

The code below uses cflow rather than withincode to
define scope, because that seems more correct to me.
The uncommented variant uses a percflow aspect, but to
demonstrate the if(..) pointcut, there's a commented
variant that uses a static ThreadLocal.

Wes
---------

import org.aspectj.lang.JoinPoint;

public class FirstAndLast {

    public static void main(String[] argList) {
        for(int i = 0; i < argList.length; i++) {
            System.out.println(argList[i]);
        }
    }
}

aspect SignalPrintlns
        extends SignalFirstEventAndLeavingScope {
    pointcut scope() : execution(void main(String[]));
    pointcut event() : call(void println(..));

    protected void handleFirstEvent(JoinPoint jp) {
        System.out.println("first event: " + jp);
    }
    protected void leavingScope(JoinPoint jp) {
        System.out.println("leaving scope: " + jp);
    }
}

/**
 * Call handleFirstEvent(..) for the first event()
 * in the control flow of scope(), and
 * call leavingScope(..) when leaving scope.
 * Subaspects must define scope() and event(),
 * and should override handleFirstEvent(..) and/or
 * leavingScope(..).
 */
abstract aspect SignalFirstEventAndLeavingScope percflow(scope()){

    boolean afterEvent;

    abstract pointcut event();
    abstract pointcut scope();

    /** default implementation does nothing */
    protected void handleFirstEvent(JoinPoint jp) {
    }

    /** default implementation does nothing */
    protected void leavingScope(JoinPoint jp) {
    }

    before() : event() &&
            !within(SignalFirstEventAndLeavingScope+) {
        if (!afterEvent) {
            afterEvent = true;
            handleFirstEvent(thisJoinPoint);
        }
    }

    after() : scope() {
        if (afterEvent) {
            leavingScope(thisJoinPoint);
        }
        // no need to reset afterEvent,
        // since aspect is passing out of scope
    }
}

//
///**
// * Call handleFirstEvent(..) for the first event()
// * in the control flow of scope(), and
// * call leavingScope(..) when leaving scope.
// * Subaspects must define scope() and event(),
// * and should override handleFirstEvent(..) and/or
// * leavingScope(..).
// */
//abstract aspect SignalFirstEventAndLeavingScope {
//    /*
//     * Using static ThreadLocal rather than percflow aspect
//     * just to demonstrate using the if(..) pointcut.
//     */
//    // ThreadLocal signals whether event has occured
//    private static ThreadLocal afterEvent = new ThreadLocal() {
//        protected synchronized Object initialValue() {
//            return new Boolean(false);
//        }
//    };
//
//    private static boolean isAfterEvent() {
//        return ((Boolean) afterEvent.get()).booleanValue();
//    }
//
//    private static void setAfterEvent(boolean value) {
//        if (value != isAfterEvent()) {
//            afterEvent.set(new Boolean(value));
//        }
//    }
//
//    // subaspects define scope and event
//    abstract pointcut event();
//    abstract pointcut scope();
//
//    /** default implementation does nothing */
//    protected void handleFirstEvent(JoinPoint jp) {
//    }
//
//    /** default implementation does nothing */
//    protected void leavingScope(JoinPoint jp) {
//    }
//
//    before() :  cflow(scope()) && event()
//            && if(!isAfterEvent())
//            && !within(SignalFirstEventAndLeavingScope+) {
//        // to use percflow aspect, put if(afterEvent) in body
//        setAfterEvent(true);
//        handleFirstEvent(thisJoinPoint);
//    }
//
//    after() : scope() && if(isAfterEvent()) {
//        try {
//            leavingScope(thisJoinPoint);
//        } finally {
//            setAfterEvent(false);
//        }
//    }
//}



Diana Szentivanyi wrote:

--- Gregor Kiczales <gregor@xxxxxxxxx> wrote: >

No, I want to have an aspect that takes a lock at

the
first access to a variable (this is easy to detect) and releases the

lock after
the last access to that variable (and here comes my problem).


Before thinking about this more, I want to ask why

you don't want to do

the simpler thing of just releasing the lock when the

enclosing method

terminates? It seems to me that you'll have a lot of

overhead for counting

gets/sets and figuring out which path you are on.
While I can see that
minimizing the locking window is good, I wonder if
you'll be paying so
much for it that it won't be worth it.


I see some other issues, but I wanted to ask this

question first, before

trying to think about those other issues.



   Actually, I do not want to count gets/sets. I do
not want to detect (by code in an advice) where is the
first access to a variable, either. If I would do the lock take/release by hand in the
application code, I would know (see) exactly where the
first and last access to a variable is. The reason why I need to count accesses and compare
to a given value to detect the last access,
respectively use a boolean variable and simple test to
detect the first access, is that I did not figure out
how to "say" in AspectJ that the "take lock" advice
code should be weaved in before only the first access,
and the "release lock" advice code should be weaved in
after only the last access.
   I know that there is an if(boolean_expr) that can
be used to define pointcuts, but that (as far as I
understood) only allows static variables in its
expression, and that is not good for me.

        Thank you again,
           Diana.

________________________________________________________________________
Want to chat instantly with your online friends?  Get the FREE Yahoo!
Messenger http://uk.messenger.yahoo.com/
_______________________________________________
aspectj-users mailing list
aspectj-users@xxxxxxxxxxx
http://dev.eclipse.org/mailman/listinfo/aspectj-users




Back to the top