Closed GoogleCodeExporter closed 9 years ago
Hmm. It looks like RRuleSchema is a singleton, but shares a ruleStack which
makes it
not reentrant. The 3rd stack frame in the above would seem to manipulate the
ruleStack, so that's probably the cause of this exception.
I think the fix to your immediate problem is to make RRuleSchema not a
singleton.
Are you sharing RRule or RecurrenceIterator instances across threads?
Can you tell me how many threads (10s, 100s) you typically use? Knowing that
would
help me put together a unittest for the parser that reproduces your problem.
Original comment by mikesamuel@gmail.com
on 13 Feb 2008 at 6:48
We have developed a wrapper class around the google classes: the class
ICalendar.
Each thread has its own instance of ICalendar as a method variable.
The problem already happens with about 5 threads.
I noticed that no synchronization has been used in IcalSchema. This class holds
an
instance variable:
private List<String> ruleStack = new ArrayList<String>();
The method
applyContentSchema (line 108, belongs to stack trace in the first comment)
manipulates the variable ruleStack, without any synchronization.
IcalSchema.applyContentSchema is used by a static variable of the class
RRuleSchema
(see RRuleSchema, line 158, belongs to stack trace in the first comment).
This part is also not synchronized.
I think that there are the reasons why our application dies with an exception.
Below, a code snippet from our class ICalendar:
public Date getNextDate( Date startDate ) throws ParseException
{
return getNextDateList( startDate, 1 ).get( 0 );
}
public List<Date> getNextDateList( Date startDate, int count ) throws ParseException
{
LocalDateIterable localDateIterable = null;
List<Date> dateList = new LinkedList<Date>();
String iCalString = rrule.toIcal();
boolean isFirstDate = true;
int index = 0;
int limit = 0;
if ( startDate == null )
{
throw new IllegalArgumentException( "startDate must not be null." );
}
if ( count < 1 )
{
throw new IllegalArgumentException( "Invalid count value: " + count );
}
// count + 1 because the first date returned is the startDate.
limit = count + 1;
localDateIterable = LocalDateIteratorFactory.createLocalDateIterable( iCalString,
new LocalDate( startDate ), true );
// A RRULE can contain a COUNT attribute according to RFC2445.
// Loops until COUNT is reached or the limit is reached.
for ( Iterator iterator = localDateIterable.iterator(); iterator.hasNext() &&
index < limit; index++ )
{
LocalDate date = (LocalDate) iterator.next();
if ( isFirstDate )
{
// The first date is the startDate. Don't get it.
isFirstDate = false;
}
else
{
dateList.add( date.toDateTimeAtStartOfDay().toDate() );
}
}
return dateList;
}
I hope that it helps you to resolve this bug.
Original comment by jcro...@gmail.com
on 14 Feb 2008 at 8:01
Original comment by mikesamuel@gmail.com
on 18 Feb 2008 at 4:40
Fixed in r22: http://code.google.com/p/google-rfc-2445/source/detail?r=22
Original comment by mikesamuel@gmail.com
on 18 Feb 2008 at 5:44
Original issue reported on code.google.com by
jcro...@gmail.com
on 13 Feb 2008 at 1:19