Lines 79-89
Link Here
|
79 |
private ServletConfig config; |
79 |
private ServletConfig config; |
80 |
private Options options; |
80 |
private Options options; |
81 |
private boolean firstTime = true; |
81 |
private boolean firstTime = true; |
82 |
private boolean reload = true; |
82 |
/** Whether the servlet needs reloading on next access */ |
|
|
83 |
private volatile boolean reload = true; |
83 |
private boolean isTagFile; |
84 |
private boolean isTagFile; |
84 |
private int tripCount; |
85 |
private int tripCount; |
85 |
private JasperException compileException; |
86 |
private JasperException compileException; |
86 |
private long servletClassLastModifiedTime; |
87 |
/** Timestamp of last time servlet resource was modified */ |
|
|
88 |
private volatile long servletClassLastModifiedTime; |
87 |
private long lastModificationTest = 0L; |
89 |
private long lastModificationTest = 0L; |
88 |
private Entry<JspServletWrapper> ticket; |
90 |
private Entry<JspServletWrapper> ticket; |
89 |
|
91 |
|
Lines 131-136
Link Here
|
131 |
} |
133 |
} |
132 |
|
134 |
|
133 |
public Servlet getServlet() throws ServletException { |
135 |
public Servlet getServlet() throws ServletException { |
|
|
136 |
// DCL on 'reload' requires that 'reload' be volatile |
137 |
// (this also forces a read memory barrier, ensuring the |
138 |
// new servlet object is read consistently) |
134 |
if (reload) { |
139 |
if (reload) { |
135 |
synchronized (this) { |
140 |
synchronized (this) { |
136 |
// Synchronizing on jsw enables simultaneous loading |
141 |
// Synchronizing on jsw enables simultaneous loading |
Lines 139-145
Link Here
|
139 |
// This is to maintain the original protocol. |
144 |
// This is to maintain the original protocol. |
140 |
destroy(); |
145 |
destroy(); |
141 |
|
146 |
|
142 |
Servlet servlet = null; |
147 |
final Servlet servlet; |
143 |
|
148 |
|
144 |
try { |
149 |
try { |
145 |
InstanceManager instanceManager = InstanceManagerFactory.getInstanceManager(config); |
150 |
InstanceManager instanceManager = InstanceManagerFactory.getInstanceManager(config); |
Lines 160-165
Link Here
|
160 |
|
165 |
|
161 |
theServlet = servlet; |
166 |
theServlet = servlet; |
162 |
reload = false; |
167 |
reload = false; |
|
|
168 |
// Volatile 'reload' forces in order write of 'theServlet' and new servlet object |
163 |
} |
169 |
} |
164 |
} |
170 |
} |
165 |
} |
171 |
} |
Lines 186-191
Link Here
|
186 |
* @param lastModified Last-modified time of servlet class |
192 |
* @param lastModified Last-modified time of servlet class |
187 |
*/ |
193 |
*/ |
188 |
public void setServletClassLastModifiedTime(long lastModified) { |
194 |
public void setServletClassLastModifiedTime(long lastModified) { |
|
|
195 |
// DCL requires servletClassLastModifiedTime be volatile |
196 |
// to force read and write barriers on access/set |
197 |
// (and to get atomic write of long) |
189 |
if (this.servletClassLastModifiedTime < lastModified) { |
198 |
if (this.servletClassLastModifiedTime < lastModified) { |
190 |
synchronized (this) { |
199 |
synchronized (this) { |
191 |
if (this.servletClassLastModifiedTime < lastModified) { |
200 |
if (this.servletClassLastModifiedTime < lastModified) { |