Personal tools
You are here: Home Data Concurrency bug patterns Case8

Case8

A unexpected operation is executed between an XHR request and the response event handler operation

Description

Between an XmlHttpRequest (XHR) request and response, another event such as a user event can be triggered. If another event, request and response read same variable, a concurrency bug can occur. In this example, line 12 in case8.html set a variable list at null, and response event handler at line 13 of case8.html assigns values in list. A function button2Clicked reads list in line 27. So, if a user clicks button1 and button2, and response event handler has not been called, the bug occurs.

Example

http://pswlab.kaist.ac.kr:81/case8.html

Reference

"Is setting interval right way to make sure Ajax call is completed?", http://t2790.codeinpro.us/q/508146514f1eba38a44bffc2

Source code

case8.html

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4.         <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  5.         <title>Case8</title>
  6. </head>
  7. <body>
  8.         <iframe src="case8_i.html"></iframe><br />
  9.         <script src="jquery-1.9.1.js"></script>
  10.         <script>
  11.                 function button1Clicked() {
  12.                         list = null;
  13.                         jQuery.getJSON("case8.txt",{},function(result) {
  14.                                 list = result;
  15.                                 jQuery.each(result.result, function(i, obj) {
  16.                                         list[i] = obj;
  17.                                 });
  18.                                 document.getElementById("outputList").innerHTML = "";
  19.                                 for (var i = 0; i < 30; i++) {
  20.                                         document.getElementById("outputList").innerHTML += list[i] + "<br>";
  21.                                 }
  22.                         });
  23.                 }
  24.                 function button2Clicked() {
  25.                         var avg = 0;
  26.                         for (var i = 0; i < 30; i++) {
  27.                                 avg += list[i];
  28.                         }
  29.                         document.getElementById("outputAverage").innerHTML = "Avg. : " + (avg / 30);
  30.                 }
  31.         </script>
  32.         <button onclick="button1Clicked()">Button1</button>
  33.         <div id="outputList" style="float: right;"></div>
  34.         <script src="dummy.js"></script>
  35.         <button onclick="button2Clicked()">Button2</button>
  36.         <div id="outputAverage"></div>  
  37. </body>
  38. </html>

case8_i.html

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4.         <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  5.         <title>Case8 iframe</title>
  6. </head>
  7. <body>
  8.         <script>        
  9.                 function image1Loaded() {
  10.                         document.getElementById("outputImage1").innerHTML = "Image1 is loaded";
  11.                 }
  12.         </script>
  13.         <div id="outputImage1"></div>
  14.         <img src="image1.jpg" height="100" witdth="100" onload="image1Loaded()">
  15. </body>
  16. </html>

case8.txt

  1. {"result":[16,53,63,83,49,39,1,59,71,55,90,95,1,38,27,94,60,58,92,73,85,77,47,0,40,23,39,75,63,67]}

dummy.js

  1. // dummy. works noting.
  2. // dummy. works noting.
  3. // dummy. works noting.

Execution Model

Operations and an Inital Test Case

There are 8 operations in this example.

  • p1: parsing operation, parse line 1~8 of case8.html
  • p2: parsing operation, parse line 9~33 of case8.html
  • p3: parsing operation, parse dummy.js and line 34~38 of case8.html
  • p4: parsing operation, parse case8_i.html
  • n1: network operation, trigger onreadystatechange (response) event of case8.txt
  • n2: network operation, trigger onload event of image1.jpg
  • u1: user event operation, trigger onclick event of button1
  • u2: user event operation, trigger onclick event of button2

The inital test case: p1 - p2 - p3 - p4 - n1 - n2 - u1 - u2

Happens-before Relations

  • For two parsing operations: (p1, p2), (p2, p3), (p1, p4)
  • For two user event operations: (u1, u2)
  • For a parsing operation and a user event operation: (p2, u1), (p3, u2)
  • For a network operation: (u1, n1), (p4, n2)

Generated Possible Test Cases

105 test cases are generated and 42 test cases of them are buggy because they contains (u2, n1).

Document Actions