Index: drsdaq/DAQReadout.cc
===================================================================
--- drsdaq/DAQReadout.cc	(revision 230)
+++ drsdaq/DAQReadout.cc	(revision 254)
@@ -57,5 +57,5 @@
 
 // Global pointer for thread entry routines
-class DAQReadout *This;
+class DAQReadout *ThisClass;
 
 // -----------------------------------------------
@@ -67,6 +67,6 @@
 
   // Initialization
-  This = this;
-  MainThread = getpid();
+  ThisClass = this;
+  MainThread = pthread_self();
   ConsoleText = NULL;
   time(&StartTime);
@@ -74,9 +74,4 @@
   // DIM console service used in PrintMessage()
   ConsoleOut = new DimService(SERVER_NAME"/ConsoleOut", (char *) "");
-
-  // Initialize mutex for thread synchronisation
-  if (pthread_mutex_init(&Mutex, NULL) != 0) {
-    Message(FATAL, "pthread_mutex_init() failed");
-  }
 
   // Initialize status structure
@@ -169,6 +164,4 @@
   delete ConsoleOut;
   free(ConsoleText);
-  
-  if (pthread_mutex_destroy(&Mutex) != 0) Message(ERROR, "pthread_mutex_destroy() failed");
 }
 
@@ -202,17 +195,6 @@
   else if(CommandList[Count].NeedNotBusy && NumBoards==0) PrintMessage("No boards available\n");
   else {
-	int Ret;
-
-	// Lock (Execute() runs in thread spawned by commandHandler())
-	if ((Ret = pthread_mutex_lock(&Mutex)) != 0) {
-	  Message(FATAL, "pthread_mutex_lock() failed (%s)", strerror(Ret));
-  	}
-	// Run command
 	CmdNumber = Count;
 	(this->*CommandList[CmdNumber].CommandPointer)();
-	// Unlock
-	if ((Ret = pthread_mutex_unlock(&Mutex)) != 0) {
-	  Message(FATAL, "pthread_mutex_unlock() failed (%s)", strerror(Ret));
-  	}
   }
 }
@@ -238,5 +220,5 @@
 // Print DAQ configuration
 void DAQReadout::cmd_config() {
-  PrintConfig(MsgToConsole);
+  PrintConfig();
 }
 
@@ -411,11 +393,11 @@
   } 
 
-  PrintMessage(MsgToConsole, "==START== %d %.2f %.2f ",kNumberOfBins+2,DRSFreq[Board],GetBoard(Board)->GetPrecision());
+  PrintMessage("==START== %d %.2f %.2f ",kNumberOfBins+2,DRSFreq[Board],GetBoard(Board)->GetPrecision());
   for (int k=0; k<kNumberOfBins; k++) {
-    PrintMessage(MsgToConsole, "%.1f ", (float) WaveForm[Board][Chip][Channel][k]);
-  }
-  PrintMessage(MsgToConsole, "==END==");
-  PrintMessage(MsgToConsole, "\n");
-  PrintMessage(MsgToConsole, "Trigger cell: %d\n", TriggerCell[Board][Chip]);  
+    PrintMessage("%.1f ", (float) WaveForm[Board][Chip][Channel][k]);
+  }
+  PrintMessage("==END==");
+  PrintMessage("\n");
+  PrintMessage("Trigger cell: %d\n", TriggerCell[Board][Chip]);  
 } 
 
@@ -757,7 +739,7 @@
   for(unsigned int i=0; i<sizeof(CommandList)/sizeof(CL_Struct); i++) {
     snprintf(Buffer, sizeof(Buffer), "%s %s", CommandList[i].Name, CommandList[i].Parameters);
-    PrintMessage(MsgToConsole, "%-28s%s\n", Buffer, CommandList[i].Help);
+    PrintMessage("%-28s%s\n", Buffer, CommandList[i].Help);
   }     
-  PrintMessage(MsgToConsole,".<command>                  Execute shell command\n\n"
+  PrintMessage(".<command>                  Execute shell command\n\n"
    "Items in <> are mandatory, in [] optional, | indicates mutual exclusive or.\n"
    "Test data can also be written if no DRS boards are available.\n"
@@ -770,5 +752,5 @@
 
   if (daq_state == active) PrintMessage("Issue 'stop' first to stop daq\n");
-  else kill(MainThread, SIGTERM);  
+  else pthread_kill(MainThread, SIGTERM);  
 }
 
@@ -777,7 +759,7 @@
 
   if(Match(Param[1],"off")) HVFB->SetFBMode(FB_Off);
-  if(Match(Param[1],"active")) HVFB->SetFBMode(FB_Active);
-  if(Match(Param[1],"targets")) HVFB->SetFBMode(FB_Targets);
-  HVFB->GetFBMode();
+  else if(Match(Param[1],"active")) HVFB->SetFBMode(FB_Active);
+  else if(Match(Param[1],"targets")) HVFB->SetFBMode(FB_Targets);
+  else HVFB->GetFBMode();
 }
 
@@ -823,5 +805,5 @@
 void DAQReadout::cmd_fconfig() {
 
-  HVFB->PrintConfig(MsgToConsole);
+  HVFB->PrintConfig();
 }
 
@@ -1175,6 +1157,6 @@
 
 // Print configuration to target
-void DAQReadout::PrintConfig(int Target) {
-  PrintMessage(Target, "RawDataPath: %s\n"
+void DAQReadout::PrintConfig() {
+  PrintMessage("RawDataPath: %s\n"
       	       "DefaultFrequency: %.2f\tFirstSample: %d\tSamples: %u\n"
      	       "MinDiskSpaceMB: %u\tMaxFileSizeMB: %d\n"
@@ -1191,46 +1173,27 @@
 // Print progress (used in DRS class)
 void DAQReadout::Progress(int Progress) {
-  PrintMessage(MsgToConsole, "\rProgress: %d%%              ", Progress);
+  PrintMessage("\rProgress: %d%%              ", Progress);
   fflush(stdout);
 };
- 
-// Print message to selected target
-void DAQReadout::PrintMessage(int Target, const char *Format, ...) {
-
-  va_list ArgumentPointer;
-  va_start(ArgumentPointer, Format); 
-  DoPrintMessage(Format, ArgumentPointer, Target);
-  va_end(ArgumentPointer);
-}
 
 // Print message to console only
 void DAQReadout::PrintMessage(const char *Format, ...) {
+
+  static char Error[] = "vasprintf() failed in PrintMessage()";
+  char *Text;
+
+  // Evaluate arguments
   va_list ArgumentPointer;
   va_start(ArgumentPointer, Format);
-  DoPrintMessage(Format, ArgumentPointer, MsgToConsole);
+  if (vasprintf(&Text, Format, ArgumentPointer) == -1) Text = Error;
   va_end(ArgumentPointer);
-}
-
-// Function doing the actual printing work
-// Note: Be careful when overloading variadic functions. va_list is
-// in gcc an int, which can be interpreted as char *...
-void DAQReadout::DoPrintMessage(const char *Format, va_list ArgumentPointer, int Target) {
-
-  static char Error[] = "vasprintf() failed in DoPrintMessage()";
-  char *Text;
-
-  // Evaluate arguments    
-  if (vasprintf(&Text, Format, ArgumentPointer) == -1) Text = Error;
   
   // Print to console
-  if(Target & MsgToConsole) {
-    if(strlen(Text)>0 && Text[strlen(Text)-1]=='\n') printf("\r%s%s", Text, Prompt);  // New prompt
-    else printf("%s", Text);
-	fflush(stdout);
-  }
-  
-  // Send to DIM console service and to log if requested
-  ConsoleOut->updateService(Text);
-  if(Target & MsgToLog) SendToLog("%s %s", SERVER_NAME, Text);
+  if(strlen(Text)>0 && Text[strlen(Text)-1]=='\n') printf("\r%s%s", Text, Prompt); // New prompt
+  else printf("%s", Text);
+  fflush(stdout);
+
+  // Send to DIM text service
+  ConsoleOut->updateService(Text); 
 
   // Free old text
@@ -1246,7 +1209,4 @@
   	  *((char *) getCommand()->getData()+getCommand()->getSize()-1) != '\0' ||
 	  strlen(getCommand()->getString()) == 0) return;
-
-  // Log command reception
-  SendToLog("Command '%s' from %s (ID %d)", getCommand()->getString(), getClientName(), getClientId());
 
   // Copy command to new buffer (will be freed by global Execute() function)
@@ -1263,8 +1223,6 @@
     PrintMessage("pthread_create() failed in DRSReadout::commandHandler() (%s)\n", strerror(Code));
   }
-  else {
-    if ((Code = pthread_detach(Thread)) != 0) {
-	  PrintMessage("pthread_detach() failed in DRSReadout::commandHandler() (%s)\n", strerror(Code));
-	}
+  else if ((Code = pthread_detach(Thread)) != 0) {
+	PrintMessage("pthread_detach() failed in DRSReadout::commandHandler() (%s)\n", strerror(Code));
   }  
 }
@@ -1459,5 +1417,7 @@
 void Execute(char *Command) {
 
- This->Execute(Command);
- free(Command);
-}
+  ThisClass->Lock();
+  ThisClass->Execute(Command);
+  free(Command);
+  ThisClass->Unlock();
+}
Index: drsdaq/DAQReadout.h
===================================================================
--- drsdaq/DAQReadout.h	(revision 230)
+++ drsdaq/DAQReadout.h	(revision 254)
@@ -12,9 +12,7 @@
 #include <unistd.h>
 #include <sys/socket.h>
-#include <pthread.h>
 #include <fcntl.h>
 #include <dirent.h>
 #include <sys/vfs.h>
-#include <signal.h>
 #include <sys/time.h>
 
@@ -26,7 +24,4 @@
 #define MAX_COM_SIZE 10000
 #define MAX_NUM_TOKEN 10
-
-#define MsgToConsole 1
-#define MsgToLog 2
 
 enum state_enum {active, stopped};
@@ -47,5 +42,4 @@
 	void commandHandler();
 
-    pthread_mutex_t Mutex;
     int Rawfile;
     class HVFeedback* HVFB;
@@ -127,8 +121,6 @@
     bool ReadCalibration();
     void ReadCalibratedDRSData();
-    void PrintConfig(int);
-    void PrintMessage(int, const char*, ...);
+    void PrintConfig();
     void PrintMessage(const char*, ...);
-    void DoPrintMessage(const char*, va_list, int); 
     bool OpenRawFile();
     bool WriteRunHeader();
Index: drsdaq/HVFeedback.cc
===================================================================
--- drsdaq/HVFeedback.cc	(revision 230)
+++ drsdaq/HVFeedback.cc	(revision 254)
@@ -30,5 +30,4 @@
 
   m = DAQClass;
-
   fNumberOfChannels = m->GetBoard(0)->GetNumberOfChannels();
   fNumberOfChips = m->GetBoard(0)->GetNumberOfChips();  
@@ -77,12 +76,11 @@
   }
   
-  PrintConfig(MsgToLog);
-
   // Provide DIM services
-  FeedbackAverage = new DimService (SERVER_NAME"/Average", "F", DIMAverage, m->NumBoards*kNumberOfChipsMax*kNumberOfChannelsMax*sizeof(float));
-  FeedbackSigma = new DimService (SERVER_NAME"/Sigma", "F", DIMSigma, m->NumBoards*kNumberOfChipsMax*kNumberOfChannelsMax*sizeof(float));
-  FeedbackResponse = new DimService (SERVER_NAME"/Response", "F", Response, m->NumBoards*kNumberOfChipsMax*kNumberOfChannelsMax*sizeof(float));
-  FeedbackTarget = new DimService (SERVER_NAME"/Target", "F", Target, m->NumBoards*kNumberOfChipsMax*kNumberOfChannelsMax*sizeof(float));
-  CountService = new DimService (SERVER_NAME"/Count", Count);
+  FeedbackAverage = new DimService ("Feedback/Average", "F", DIMAverage, m->NumBoards*kNumberOfChipsMax*kNumberOfChannelsMax*sizeof(float));
+  FeedbackSigma = new DimService ("Feedback/Sigma", "F", DIMSigma, m->NumBoards*kNumberOfChipsMax*kNumberOfChannelsMax*sizeof(float));
+  FeedbackResponse = new DimService ("Feedback/Response", "F", Response, m->NumBoards*kNumberOfChipsMax*kNumberOfChannelsMax*sizeof(float));
+  FeedbackTarget = new DimService ("Feedback/Target", "F", Target, m->NumBoards*kNumberOfChipsMax*kNumberOfChannelsMax*sizeof(float));
+  CountService = new DimService ("Feedback/Count", Count);
+  FeedbackState = new DimService ("Feedback/State", "I:1;C", NULL, 0);
 
   // Initial state
@@ -98,4 +96,5 @@
 HVFeedback::~HVFeedback() {
 
+  delete FeedbackState;
   delete CountService;
   delete FeedbackAverage;
@@ -105,5 +104,5 @@
 
   delete[] Average;   	delete[] Response;
-  delete[] DIMAverage;   	delete[] DIMSigma;
+  delete[] DIMAverage; 	delete[] DIMSigma;
   delete[] Sigma;
   delete[] Target;   	delete[] Buffer;
@@ -159,12 +158,13 @@
 	
 	switch (FBMode) {
-	  case FB_Active:   // Determine correction from response maxtrix and change voltages
+	  case FB_Active:
+		// Determine correction from response maxtrix and change voltages
 	    Correction = -(Target[i][j][k] - Average[i][j][k])*Response[i][j][k]*Gain;
-    	if (fabs(Correction) > 0.1) Correction = fabs(Correction)/Correction*0.1;   // Limit changes to 100 mV
+    	// Limit voltage steps
+		if (fabs(Correction) > 0.1) Correction = fabs(Correction)/Correction*0.1;   // Limit changes to 100 mV
+		// Check if voltage change command possible
 		if(Correction==0 || Target[i][j][k]==0 || PixMap->DRS_to_Pixel(i,j,k).empty()) break;
-        printf("Average of board %d, chip %d, channel %d is %.2f +/- %.2f    Correction %.3f\n",i,j,k,Average[i][j][k],Sigma[i][j][k],Correction);
-
-		if(fabs(Average[i][j][k]) < 2*Sigma[i][j][k]) printf("Too noisy!\n");
-		else {
+		// Add voltage change command if not too noisy
+		if(fabs(Average[i][j][k]) > 2*Sigma[i][j][k]) {
 		  Cmd << PixMap->DRS_to_Pixel(i,j,k)+" " << std::showpos << Correction << " ";
 		}
@@ -184,5 +184,5 @@
 	  case FB_ResponseSecond: // Determine response from signal variation
 	    if(Buffer[i][j][k] == Average[i][j][k]) {
-	      m->PrintMessage("HV Feedback: Warning, response singular for board %d, chip %d, channel %d.\n",i,j,k);
+	      m->PrintMessage("HV Feedback: Warning, response singular for board %d, chip %d, channel %d\n",i,j,k);
 	      Response[i][j][k] = 0;
 	    }
@@ -211,14 +211,14 @@
     case FB_Targets:
 	  FeedbackTarget->updateService();
-      m->PrintMessage("HV Feedback: New targets set, switching off.\n");
+      m->PrintMessage("HV Feedback: New targets set, switching off\n");
       SetFBMode(FB_Off, true);
       break;
     case FB_ResponseFirst:
       SetFBMode(FB_ResponseSecond, true);
-      m->PrintMessage("HV Feedback: Increasing voltages by %f for response measurement, acquiring data.\n", DiffVoltage);
+      m->PrintMessage("HV Feedback: Increasing voltages by %f for response measurement, acquiring data\n", DiffVoltage);
       break;
     case FB_ResponseSecond:
 	  FeedbackResponse->updateService();
-      m->PrintMessage("HV Feedback: Response measurements finished, original voltages set, switching off.\n");
+      m->PrintMessage("HV Feedback: Response measurements finished, original voltages set, switching off\n");
       SetFBMode(FB_Off, true);
       break;
@@ -277,10 +277,15 @@
 void HVFeedback::SetFBMode(FBState Mode, bool Internal) {
   if((Mode==FB_ResponseFirst || Mode==FB_ResponseFirst) && !Internal)
-      m->PrintMessage("Start reponse measurement by calling MeasureResponse().\n");
+      m->PrintMessage("Start reponse measurement by calling MeasureResponse()\n");
   else {
     FBMode = Mode;
-	if (Mode != FB_ResponseFirst) m->Message(m->INFO, "%s", FBState_Description[FBMode]);
-	else m->Message(m->INFO, "%s (voltage difference %.3f)", FBState_Description[FBMode], DiffVoltage);
+	if (Mode != FB_ResponseFirst) m->PrintMessage("%s\n", FBState_Description[FBMode]);
+	else m->PrintMessage("%s (voltage difference %.3f)\n", FBState_Description[FBMode], DiffVoltage);
     ClearAverages();
+	
+	// Update state service
+	State.State = FBMode;
+	strncpy(State.Text, FBState_Description[FBMode], sizeof(State.Text));
+	FeedbackState->updateService(&State, sizeof(State));
   }
 }
@@ -374,7 +379,7 @@
 // Print feedback configuration
 //
-void HVFeedback::PrintConfig(int Target) {
-
-  m->PrintMessage(Target, "LedTrigBoard: %d\t\tLedTrigChip: %d\t\tLedTrigChannel: %d\n"
+void HVFeedback::PrintConfig() {
+
+  m->PrintMessage("LedTrigBoard: %d\t\tLedTrigChip: %d\t\tLedTrigChannel: %d\n"
         "LedTrigSample: %d\tLedTrigThreshold: %.2f\n"
         "LedSignalSample: %d\tLedBaselineSample: %d\tDefaultNumAverage: %d\n"
Index: drsdaq/HVFeedback.h
===================================================================
--- drsdaq/HVFeedback.h	(revision 230)
+++ drsdaq/HVFeedback.h	(revision 254)
@@ -33,4 +33,10 @@
 	DimService *FeedbackTarget;
 	DimService *CountService;
+	DimService *FeedbackState;
+
+	struct {
+      int State;
+	  char Text[BUF_LENGTH];
+	} State;
 
 	int NumAverages;	// Events to take before feedback acts
@@ -72,5 +78,5 @@
     void GetResponse();
     void ClearAverages();
-    void PrintConfig(int);
+    void PrintConfig();
 };
 
Index: drsdaq/History.txt
===================================================================
--- drsdaq/History.txt	(revision 230)
+++ drsdaq/History.txt	(revision 254)
@@ -58,5 +58,6 @@
 16/12/2009  Removed automatic gain adaption in feedback (caused spikes in the correction)
 9/3/2010	Feedback now depended on DIM for communication with bias server.
-			Started migration to DRS4 (last tested revision as daqct3 for DRS2 is 161). DRS class will not run anymore with DRS2 FPGA firmware.
+			Started migration to DRS4 (last tested revision as daqct3 for DRS2 is 161).
+			DRS class will not run anymore with DRS2 FPGA firmware.
 11/3/2010	Removed SlowData class.			
 12/3/2010	Removed local configuration and logging.
@@ -67,2 +68,4 @@
 18/5/2010	Rate of event service adjustable with command 'update'.
 21/5/2010	Fix so that 'exit' command also works as DimCommand.
+20/7/2010	Replaced mutex with Lock()/Unlock() from Evidence class, introduced DIM feedback state service,
+			streamlined PrintMessage(). 
Index: drsdaq/drsdaq.cpp
===================================================================
--- drsdaq/drsdaq.cpp	(revision 230)
+++ drsdaq/drsdaq.cpp	(revision 254)
@@ -91,5 +91,5 @@
 	DimClient::sendCommand(SERVER_NAME"/Command", Command);
     free(Command);
-  }  
+  }
 }
 
@@ -97,4 +97,5 @@
 // Remove lock file before running default signal code
 void CrashHandler(int Signal) {
+
   remove(LOCKFILE);
   printf("Caught signal number %d. Removed lockfile and performing standard signal action. Good luck.\n",Signal);
