+(in-package #:candle)
+
+(defvar *mutex* (sb-thread:make-mutex))
+(defvar *waitq* (sb-thread:make-waitqueue))
+
+(defvar *job-system*)
+(defgeneric process-job-in-system (job-system job))
+
+(defun start-processor-thread ()
+ (sb-thread:make-thread
+ (lambda ()
+ (loop
+ (let
+ ((job (find :queued *all-job* :key #'job-status)))
+ (if job
+ (process-job job)
+ ; We just wait here until the processor is released, which is usually done
+ ; when a project is refreshed.
+ (sb-thread:with-mutex (*mutex*)
+ (sb-thread:condition-wait *waitq* *mutex*))))))
+ :name "Processor"))
+
+(defun awaken-processor-thread ()
+ (sb-thread:with-mutex (*mutex*)
+ (sb-thread:condition-broadcast *waitq*)))
+
+(defun process-job (job)
+ (set-job-status job :in-progress)
+ (git (job-project job) "checkout" (job-sha job))
+ (if (not (probe-file (format nil "~A.candle" (project-dir (job-project job)))))
+ (set-job-status job :no-candle-file)
+ (multiple-value-bind (result log) (process-job-in-system *job-system* job)
+ (set-job-status job (if result :succeeded :failed))
+ (set-job-log job log))))