Skip to Main Content

APEX

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

Potential race condition within htmdb_Get

476328Aug 28 2007 — edited Aug 28 2007
Our application makes heavy use of PPR to give us that wonderful AJAX feel.
Recently we stumbled across a potential race condition within htmldb_Get

What we found was that two consecutive htmldb_Get requests (for example two PPRs done in quick succession) can cause a race condition within htmldb_Get potentially resulting in a null value error.

The cause of this problem is as follows:

Line 172 and 181:
var ie_HACK = 'htmldb_get_WriteResult()';
setTimeout(ie_HACK,100);
These two lines create a timeout which runs htmldb_get_WriteResult() after 100 milliseconds.

Now imagine that two PPRs are run in rapid succession.
This causes a race condition on the global variable gNode!


Execution example:
PPR-1 is executed
PPR-1 creates a timeout and finishes
PPR-1 timeout is now waiting for 100 milliseconds

PPR-2 is executed
PPR-2 creates a timeout and finishes
PPR-2 timeout is waiting for 100 milliseconds

PPR-1 wakes up
PPR-1 runs line 196 ( if(gNode && ... ) )

PPR-1 runs line 199 ( gNode.innerHTML = gResult; )
PPR-2 wakes up

PPR-1 runs line 201 ( gResult = null; )
PPR-2 runs line 196 ( if(gNode && ... ) )

PPR-1 runs line 202 ( gNode = null; )
PPR-2 runs line 199 ( gNode.innerHTML = gResult; )
PPR-2 gets null value error!
Because gNode is global and is modified by both functions it causes this race condition.
One suggested change would be to use setTimeout with a function as a closure as its argument instead of a string.


To implement this, change htmldb_get_WriteResult to something like:
function htmldb_get_WriteResult( updateNode, updateResult ) {
	if( updateNode ) {
		if( updateNode.nodeName == 'INPUT' || updateNode.nodeName == 'TEXTAREA' ) {
			updateNode.value = updateResult;
		} else {
			updateNode.innerHTML = updateResult;
		}
	}
}
And modify all instances of:
var ie_HACK = 'htmldb_get_WriteResult()';
setTimeout(ie_HACK,100);
To something like:
setTimeout( function() { htmldb_get_WriteResult( gNode, gResult ); }, 100 );
Comments
Locked Post
New comments cannot be posted to this locked post.
Post Details
Locked on Sep 25 2007
Added on Aug 28 2007
2 comments
285 views