Race Problem: PinnedDispatcher
There is a non atomic check/modify operation in the register method.
So it can be that a check is done if there already is an owner and no owner is found bu one thread. But then a different thread comes in and registers itself completely (so sets the owner) and now the original thread continues and also does super.register(actorRef) since result of owner.compareAndSet(null,actorRef) will be false in this particular case.
override def register(actorRef: ActorRef) = {
val actor = owner.get()
if ((actor ne null) && actorRef != actor) throw new IllegalArgumentException("Cannot register to anyone but " + actor)
owner.compareAndSet(null, actorRef) //Register if unregistered
super.register(actorRef)
}
So it can be that a check is done if there already is an owner and no owner is found bu one thread. But then a different thread comes in and registers itself completely (so sets the owner) and now the original thread continues and also does super.register(actorRef) since result of owner.compareAndSet(null,actorRef) will be false in this particular case.
override def register(actorRef: ActorRef) = {
val actor = owner.get()
if ((actor ne null) && actorRef != actor) throw new IllegalArgumentException("Cannot register to anyone but " + actor)
owner.compareAndSet(null, actorRef) //Register if unregistered
super.register(actorRef)
}
Leave a comment
Only use is called by:
final def attach(actorRef: ActorRef) {
guard withGuard {
register(actorRef)
}
}
So completely safe
final def attach(actorRef: ActorRef) {
guard withGuard {
register(actorRef)
}
}
So completely safe
Updating tickets (#967, #974, #975, #976, #980, #981, #989, #990, #992, #993, #994, #999, #1000, #1004, #1008, #1011, #1015, #1018, #1022, #1023, #1024, #1025, #1027, #1028, #1029, #1030, #1032, #1033, #1036, #1047, #1053, #1062, #1067, #1068, #1069, #1072, #1075, #1078, #1082, #1102, #1107, #1110, #1111, #1115, #1116, #1121, #1122, #1123, #1124)