Patch title: Release 85 bulk changes
Abstract:
File: /pliant/language/debug/log.pli
Key:
    Removed line
    Added line
module "/pliant/language/unsafe.pli"
module "/pliant/language/stream.pli"
module "/pliant/admin/file.pli"
module "/pliant/language/debug/trace.pli"

type LogTrace
  field Stream stream ; field CBool flushed
  field Intn mini maxi ; field Sem file_sem rotate_sem

TraceHandler maybe LogTrace

method log line message
  arg_rw LogTrace log ; arg Str message
  log:file_sem request
  log:stream writeline string:datetime+" "+message
  log flushed := false
  log:file_sem release

method log flush
  arg_rw LogTrace log
  if not log:flushed
    log:file_sem request
    log:stream flush anytime
    log flushed := true
    if ((log:stream query "seek") parse (var Intn size)) and size>log:maxi
      if log:rotate_sem:nowait_request
        thread
          share log
          var Str name := log:stream name
          (var Stream src) open name in+safe
          src configure "seek "+(string size-log:mini)
          src readline
          (var Stream dest) open name+".tmp" out+safe
          while (raw_copy src dest 1 2^24)<>0
            void
          log:file_sem request
          log:stream close
          while (raw_copy src dest 1 2^24)<>0
            void
          src close
          dest close
          file_delete name
          file_move name+".tmp" name
          log:stream open name append+safe
          log:file_sem release
          log:rotate_sem release
    log:file_sem release


function trace_log service filename mini maxi
  arg Str service filename ; arg Intn mini maxi
  var Link:LogTrace log :> new LogTrace
  log:stream open filename append+safe ; log flushed := true
  log mini := mini ; log maxi := maxi
  trace_slots_sem request
  var Pointer:Arrow cc :> trace_slots:first
  while cc<>null
    var Pointer:TraceSlot slot2 :> cc map TraceSlot
    if slot2:name=service
      log bind slot2
    cc :> trace_slots next cc
  trace_slots_sem release
  if false
    trace_slots_sem request
    var Pointer:Arrow cc :> trace_slots:first
    while cc<>null
      var Pointer:TraceSlot slot2 :> cc map TraceSlot
      if slot2:name=service
        log unbind slot2
        cc :> trace_slots next cc
    trace_slots_sem release


export trace_log