Changeset 4306

Show
Ignore:
Timestamp:
06/09/08 09:01:54 (4 months ago)
Author:
pmoura
Message:

Corrected a bug in the implementation of the built-in meta-predicate threaded/1 when canceling individual threads that resultd from a leak of thread results between calls to the threaded/1 predicate.

Location:
trunk
Files:
2 modified

Legend:

Unmodified
Added
Removed
  • trunk/compiler/logtalk.pl

    r4305 r4306  
    1320313203 
    1320413204 
    13205 '$lgt_mt_threaded_and_exit'(terminate, _, Ids, _) :- 
    13206     '$lgt_mt_threaded_call_cancel'(Ids), 
     13205'$lgt_mt_threaded_and_exit'(terminate, _, Ids, Results) :- 
     13206    '$lgt_mt_threaded_call_cancel'(Ids, Results), 
    1320713207    throw('$lgt_terminated'). 
    1320813208 
     13209% messages can arrive out-of-order; if that's the case we need to keep looking for the 
     13210% thread result that lead to the termination of the other threads 
     13211 
    1320913212'$lgt_mt_threaded_and_exit'(exception(Error), Id, Ids, Results) :- 
     13213    '$lgt_mt_threaded_record_result'(Results, Id, exception(Error)), 
    1321013214    (   Error == '$lgt_terminated' -> 
    1321113215        '$lgt_mt_threaded_and_exit'(Ids, Results) 
    13212     ;   '$lgt_mt_threaded_call_cancel'(Ids, Id), 
     13216    ;   '$lgt_mt_threaded_call_cancel'(Ids, Results, Id), 
    1321313217        throw(Error) 
    1321413218    ). 
     
    1321813222    '$lgt_mt_threaded_and_add_result'(Results, Id, TGoal, Continue), 
    1321913223    (   Continue == false -> 
    13220         '$lgt_mt_threaded_call_join'(Ids) 
     13224        '$lgt_mt_threaded_call_join'(Ids, Results) 
    1322113225    ;   '$lgt_mt_threaded_and_exit'(Ids, Results) 
    1322213226    ). 
    1322313227 
    13224 '$lgt_mt_threaded_and_exit'(false, Id, Ids, _) :- 
    13225     '$lgt_mt_threaded_call_cancel'(Ids, Id), 
     13228'$lgt_mt_threaded_and_exit'(false, Id, Ids, Results) :- 
     13229    '$lgt_mt_threaded_record_result'(Results, Id, false), 
     13230    '$lgt_mt_threaded_call_cancel'(Ids, Results, Id), 
    1322613231    fail. 
    1322713232 
     
    1324213247    (   var(Done) -> 
    1324313248        Continue = true     % we found a thread whose result is still pending 
    13244     ;   true                % otherwise continue examining the reamaining thread results 
     13249    ;   true                % otherwise continue examining the remaining thread results 
    1324513250    ), 
    1324613251    '$lgt_mt_threaded_and_add_result'(Results, Id, TGoal, Continue). 
     
    1326913274 
    1327013275 
    13271 '$lgt_mt_threaded_or_exit'(terminate, _, Ids, _) :- 
    13272     '$lgt_mt_threaded_call_cancel'(Ids), 
     13276'$lgt_mt_threaded_or_exit'(terminate, _, Ids, Results) :- 
     13277    '$lgt_mt_threaded_call_cancel'(Ids, Results), 
    1327313278    throw('$lgt_terminated'). 
    1327413279 
     13280% messages can arrive out-of-order; if that's the case we need to keep looking for the 
     13281% thread result that lead to the termination of the other threads 
     13282 
    1327513283'$lgt_mt_threaded_or_exit'(exception(Error), Id, Ids, Results) :- 
     13284    '$lgt_mt_threaded_record_result'(Results, Id, exception(Error)), 
    1327613285    (   Error == '$lgt_terminated' -> 
    1327713286        '$lgt_mt_threaded_or_exit'(Ids, Results) 
    13278     ;   '$lgt_mt_threaded_call_cancel'(Ids, Id), 
     13287    ;   '$lgt_mt_threaded_call_cancel'(Ids, Results, Id), 
    1327913288        throw(Error) 
    1328013289    ). 
     
    1328213291'$lgt_mt_threaded_or_exit'(true, Id, Ids, Results) :- 
    1328313292    thread_get_message('$lgt_result'(Id, TGoal)), 
    13284     '$lgt_mt_threaded_call_cancel'(Ids, Id), 
     13293    '$lgt_mt_threaded_record_result'(Results, Id, true), 
     13294    '$lgt_mt_threaded_call_cancel'(Ids, Results, Id), 
    1328513295    '$lgt_mt_threaded_or_exit_unify'(Results, Id, TGoal). 
    1328613296 
     
    1329013300        '$lgt_mt_threaded_or_exit'(Ids, Results) 
    1329113301    ;   % all goals failed 
    13292         '$lgt_mt_threaded_call_join'(Ids), 
     13302        '$lgt_mt_threaded_call_join'(Ids, Results), 
    1329313303        fail 
    1329413304    ). 
     
    1329813308% unifies the successful thread goal result with the original call 
    1329913309 
    13300 '$lgt_mt_threaded_or_exit_unify'([id(Id, TGoal, _)| _], Id, TGoal) :- 
     13310'$lgt_mt_threaded_or_exit_unify'([id(Id, TGoal, true)| _], Id, TGoal) :- 
    1330113311    !. 
    1330213312 
     
    1330613316 
    1330713317 
     13318% '$lgt_mt_threaded_record_result'(+list, +thread_identifier, +callable) 
     13319% 
     13320% records a thread goal result: 
     13321 
     13322'$lgt_mt_threaded_record_result'([id(Id, _, Result)| _], Id, Result) :- 
     13323    !. 
     13324 
     13325'$lgt_mt_threaded_record_result'([_| Results], Id, Result) :- 
     13326    '$lgt_mt_threaded_record_result'(Results, Id, Result). 
     13327 
     13328 
     13329 
    1330813330% '$lgt_mt_threaded_or_record_failure'(+list, +thread_identifier, -atom) 
    1330913331% 
    13310 % records a goal failure and checks if all other goals have failed: 
     13332% records a thread goal failure and checks if all other thread goals have failed: 
    1331113333 
    1331213334'$lgt_mt_threaded_or_record_failure'([id(Id, _, fail)| Results], Id, Continue) :- 
     
    1332013342    (   var(Done) -> 
    1332113343        Continue = true     % we found a thread whose result is still pending 
    13322     ;   true                % otherwise continue examining the reamaining thread results 
     13344    ;   true                % otherwise continue examining the remaining thread results 
    1332313345    ), 
    1332413346    '$lgt_mt_threaded_or_record_failure'(Results, Id, Continue). 
     
    1333713359 
    1333813360 
    13339 % '$lgt_mt_threaded_call_cancel'(+list(thread_identifier), thread_identifier) 
     13361% '$lgt_mt_threaded_call_cancel'(+list(thread_identifier), +list, +thread_identifier) 
    1334013362% 
    1334113363% aborts a threaded call by aborting and joining all individual threads; 
    1334213364% we must use catch/3 as some threads may already be terminated 
    1334313365 
    13344 '$lgt_mt_threaded_call_cancel'(Ids, ProtectedId) :- 
     13366'$lgt_mt_threaded_call_cancel'(Ids, Results, ProtectedId) :- 
    1334513367    '$lgt_mt_threaded_call_abort'(Ids, ProtectedId), 
    13346     '$lgt_mt_threaded_call_join'(Ids). 
     13368    '$lgt_mt_threaded_call_join'(Ids, Results). 
    1334713369 
    1334813370 
     
    1336113383 
    1336213384 
    13363 '$lgt_mt_threaded_call_cancel'(Ids) :- 
     13385'$lgt_mt_threaded_call_cancel'(Ids, Results) :- 
    1336413386    '$lgt_mt_threaded_call_abort'(Ids), 
    13365     '$lgt_mt_threaded_call_join'(Ids). 
     13387    '$lgt_mt_threaded_call_join'(Ids, Results). 
    1336613388 
    1336713389 
     
    1337613398 
    1337713399 
    13378 '$lgt_mt_threaded_call_join'([]). 
    13379  
    13380 '$lgt_mt_threaded_call_join'([Id| Ids]) :- 
     13400'$lgt_mt_threaded_call_join'([], []). 
     13401 
     13402'$lgt_mt_threaded_call_join'([Id| Ids], [id(Id, _, Result)| Results]) :- 
     13403    (   var(Result) -> 
     13404        thread_get_message('$lgt_status'(Id, Result)), 
     13405        (   Result == true -> 
     13406            thread_get_message('$lgt_result'(Id, _)) 
     13407        ;   true 
     13408        ) 
     13409    ;   true 
     13410    ), 
    1338113411    catch(thread_join(Id, _), _, true), 
    13382     '$lgt_mt_threaded_call_join'(Ids). 
     13412    '$lgt_mt_threaded_call_join'(Ids, Results). 
    1338313413 
    1338413414 
  • trunk/RELEASE_NOTES.txt

    r4305 r4306  
    2323    exception terms. Thanks to Joerg Schuster for the bug report. 
    2424 
    25     Corrected a bug in the implementation of the built-in meta-predicate  
    26     threaded/1 when canceling individual threads when one of them terminates  
    27     with an exception or a failure. 
     25    Corrected two bugs in the implementation of the built-in meta-predicate  
     26    threaded/1 when canceling individual threads. The first bug resulted from  
     27    out-of-order thread status messages. The second bug resultd from a leak  
     28    of thread results between calls to the threaded/1 predicate. 
    2829 
    2930    Added a new default compiler option, multifile_directive, to all config