diff --git a/src/dialogs/fl_digi.cxx b/src/dialogs/fl_digi.cxx
index 4017ba2f..8e70c06a 100644
--- a/src/dialogs/fl_digi.cxx
+++ b/src/dialogs/fl_digi.cxx
@@ -141,6 +141,7 @@
 #include "flmisc.h"
 
 #include "arq_io.h"
+#include "kmlserver.h"
 
 #include "notifydialog.h"
 #include "macroedit.h"
@@ -2828,6 +2829,8 @@ bool clean_exit(bool ask) {
 	close_logbook();
 	MilliSleep(50);
 
+	exit_process();
+
 	return true;
 }
 
diff --git a/src/include/kmlserver.h b/src/include/kmlserver.h
index 87be7143..35328a77 100644
--- a/src/include/kmlserver.h
+++ b/src/include/kmlserver.h
@@ -36,6 +36,8 @@ class KmlServer {
 protected:
 	/// Counts the number of complete messages written.
 	int m_nb_broadcasts ;
+	int exit_kml_server;
+	int request_broadcast;
 public:
 	/// List of key-value pairs displayed for example in Google Earth balloons.
 	struct CustomDataT : public std::vector< std::pair< std::string, std::string > > {
@@ -55,7 +57,7 @@ public:
 		}
 	};
 
-	KmlServer() : m_nb_broadcasts(0) {}
+	KmlServer() : m_nb_broadcasts(0), exit_kml_server(0), request_broadcast(0) {}
 
 	virtual ~KmlServer() {}
 
diff --git a/src/include/main.h b/src/include/main.h
index 0d148739..879f2350 100644
--- a/src/include/main.h
+++ b/src/include/main.h
@@ -86,6 +86,9 @@ extern bool nbems_dirs_checked;
 // This inits or reinits everything related to KML: Reloads params etc...
 void kml_init(bool load_files = false);
 
+// close down remaining threads just before exiting UI
+extern void exit_process();
+
 int directory_is_created( const char * strdir );
 
 #endif
diff --git a/src/main.cxx b/src/main.cxx
index 80a79dac..70fdb3fe 100644
--- a/src/main.cxx
+++ b/src/main.cxx
@@ -522,8 +522,13 @@ int main(int argc, char ** argv)
 
 	int ret = Fl::run();
 
-	arq_close();
+	return ret;
+}
 
+void exit_process() {
+
+	KmlServer::Exit();
+	arq_close();
 	XML_RPC_Server::stop();
 
 	if (progdefaults.usepskrep)
@@ -533,11 +538,9 @@ int main(int argc, char ** argv)
 		cbq[i]->detach();
 		delete cbq[i];
 	}
+
 	FSEL::destroy();
 
-	KmlServer::Exit();
-
-	return ret;
 }
 
 void generate_option_help(void) {
diff --git a/src/misc/kmlserver.cxx b/src/misc/kmlserver.cxx
index efe8c905..5623050c 100644
--- a/src/misc/kmlserver.cxx
+++ b/src/misc/kmlserver.cxx
@@ -46,9 +46,22 @@
 #include "strutil.h"
 #include "configuration.h"
 
+#include "irrXML.h"
+
 #include "timeops.h"
 
-#include "irrXML.h"
+/** Some platforms have problems with condition variables apparently.
+ * When cancelling a thread which waits in pthread_cond_timedwait,
+ * the thread is stuck.
+ * We replace it by an unconditional wait, and a test on a boolean
+ * which indicates if data was saved in the internal buffers.
+ * The consequence is that data are not immediately saved in KML files,
+ * and the user has to wait until the end of the delay.
+ */
+
+#if !defined(__APPLE__)
+#	define FLDIGI_KML_CONDITION_VARIABLE 1
+#endif
 
 // ----------------------------------------------------------------------------
 
@@ -85,7 +98,10 @@ static time_t KmlFromTimestamp( const char * ts ) {
 
 	if( 0 == strcmp( ts, KmlSrvUnique ) ) return KmlServer::UniqueEvent ;
 
-	tm objTm ;
+	/// So all fields are initialised with correct default values.
+	time_t timNow = time(NULL);
+	tm objTm = *gmtime( &timNow ); 
+
 	int r = sscanf( ts, "%4d-%02d-%02dT%02d:%02dZ",
 			&objTm.tm_year,
 			&objTm.tm_mon,
@@ -96,6 +112,7 @@ static time_t KmlFromTimestamp( const char * ts ) {
 	objTm.tm_year -= 1900;
 	objTm.tm_mon -= 1;
 	objTm.tm_sec = 0;
+
 	time_t res = mktime( &objTm );
 	if( res < 0 ) throw std::runtime_error("Cannot make timestamp from " + std::string(ts) );
 	return res;
@@ -185,12 +202,12 @@ static void KmlHeader( std::ostream & ostrm, const std::string & title ) {
 		"" << title << "\n" ;
 }
 
-// Appended at the end of each KML document.
+/// Appended at the end of each KML document.
 static const char KmlFooter[] = 
 	"\n"
 	"\n" ;
 
-// Contains for example GIF images, and all the styles. Can be customised by the user.
+/// Contains for example GIF images, and all the styles. Can be customised by the user.
 static const std::string namStyles = "styles.kml";
 
 /** Used to code the data for reloading. The description tag is too complicated
@@ -789,7 +806,6 @@ class  KmlSrvImpl : public KmlServer {
 				{
 					PlacesMapItrSetT::const_iterator itNamNxt = itNamLast;
 					++itNamNxt ;
-					assert( (*itNamBeg)->first != (*itNamLast)->first );
 					if( ( itNamNxt == itStylNext ) || ( (*itNamNxt)->first != (*itNamLast)->first ) ) {
 						// No point tracing a line with one point only.
 						if( *itNamBeg != *itNamLast ) {
@@ -852,15 +868,17 @@ class  KmlSrvImpl : public KmlServer {
 
 	/// This file copy does not need to be atomic because it happens once only.
 	void CopyStyleFileIfNotExists(void) {
-		// Where the installed file is stored. Used as default.
+		/// Where the installed file is stored and never moved from. Used as default.
 		std::string namSrc = PKGDATADIR "/kml/" + namStyles ;
 
 		/// The use might customize its styles file: It will not be altered.
 		std::string namDst = m_kml_dir + namStyles ;
 
+		/// Used to copy the master file to the user copy if needed.
 		FILE * filSrc = NULL;
 		FILE * filDst = fopen( namDst.c_str(), "r" );
-		// If the file is there, leave as it is because it is maybe customize.
+
+		/// If the file is there, leave as it is because it is maybe customize.
 		if( filDst ) {
 			LOG_INFO("Style file %s not altered", namDst.c_str() );
 			goto close_and_quit ;
@@ -875,6 +893,8 @@ class  KmlSrvImpl : public KmlServer {
 			LOG_INFO("Cannot open source style file %s", namSrc.c_str() );
 			goto close_and_quit ;
 		}
+
+		/// Transient buffer to copy the file.
     		char buffer[BUFSIZ];
     		size_t n;
 
@@ -898,7 +918,7 @@ class  KmlSrvImpl : public KmlServer {
 
 		LOG_INFO("Creating baseFil=%s", baseFil.c_str() );
 
-		// We do not need to make this file aomtic because it is read once only.
+		/// We do not need to make this file atomic because it is read once only.
 		AtomicRenamer ar( baseFil );
 
 		KmlHeader( ar, "Fldigi");
@@ -918,7 +938,7 @@ class  KmlSrvImpl : public KmlServer {
 		PlacesMapT::const_iterator beg,
 		PlacesMapT::const_iterator last ) {
 
-		// The polyline gets an id based on the beginning of the path, which will never change.
+		/// The polyline gets an id based on the beginning of the path, which will never change.
 		ostrm
 			<< "second.KmlId() << ":Path\">"
 			"" << beg->second.KmlId() << ""
@@ -1102,7 +1122,7 @@ class  KmlSrvImpl : public KmlServer {
 				if( ! avoidNode.empty() ) break ;
 
 				const char * msgTxt = xml->getNodeData();
-				// LOG_INFO( "getNodeData=%s currState=%s", msgTxt, KmlRdToStr(currState) );
+				LOG_DEBUG( "getNodeData=%s currState=%s", msgTxt, KmlRdToStr(currState) );
 				switch(currState) {
 					case KMLRD_FOLDER_NAME : 
 					       currFolderName = msgTxt ? msgTxt : "NullFolder";
@@ -1135,8 +1155,14 @@ class  KmlSrvImpl : public KmlServer {
 						if (!strcmp("Folder", nodeName)) {
 							currState = KMLRD_FOLDER ;
 						} else {
+							/// These tags are not meaningful for us.
+							if(	strcmp( "kml", nodeName ) &&
+								strcmp( "Document", nodeName ) &&
+								strcmp( "name", nodeName ) )
+							{
 							LOG_INFO("Unexpected %s in document %s. currState=%s",
 								nodeName, category.c_str(), KmlRdToStr(currState) );
+							}
 						}
 						break;
 					case KMLRD_FOLDER : 
@@ -1331,7 +1357,16 @@ class  KmlSrvImpl : public KmlServer {
 		return wasSaved ;
 	} // KmlSrvImpl::RewriteKmlFileFull
 
+#ifdef FLDIGI_KML_CONDITION_VARIABLE
+	/// This is signaled when geographic data is broadcasted.
 	pthread_cond_t  m_cond_queue ;
+#else
+	/// This is set to true when geographic data is broadcasted.
+	bool            m_bool_queue ;
+
+	/// This tells that the subthread must leave at the first opportunity.
+	bool            m_kml_must_leave;
+#endif
 	pthread_mutex_t m_mutex_write ;
 
 	typedef std::list< PlacemarkT > PlacemarkListT ;
@@ -1359,6 +1394,7 @@ class  KmlSrvImpl : public KmlServer {
 		// Endless loop until end of program, which cancels this subthread.
 		for(;;)
 		{
+#ifdef FLDIGI_KML_CONDITION_VARIABLE
 			struct timespec tmp_tim;
 			{
 				guard_lock myGuard( &m_mutex_write );
@@ -1373,6 +1409,23 @@ class  KmlSrvImpl : public KmlServer {
 					LOG_ERROR("pthread_cond_timedwait %s d=%d", strerror(errno), m_refresh_interval );
 					return (void *)"Error in pthread_cond_timed_wait";
 				}
+#else
+			/// On the platforms where pthread_cond_timedwait has problems, everything behaves
+			// as if there was a timeout when data is saved. refresh_delay is never changed.
+			for( int i = 0; i < refresh_delay; ++i )
+			{
+				MilliSleep( 1000 );
+				if( m_kml_must_leave )
+				{
+					LOG_INFO("Exit flag detected. Leaving");
+					return (void *)"Exit flag detected";
+				}
+			}
+			{
+				guard_lock myGuard( &m_mutex_write );
+				r = m_bool_queue ? ETIMEDOUT : 0 ;
+				m_bool_queue = false;
+#endif
 
 				// Except if extremely slow init, the object should be ready now: Files loaded etc...
 				if( ! m_loaded ) {
@@ -1414,10 +1467,12 @@ class  KmlSrvImpl : public KmlServer {
 
 				// Reset the interval to the initial value.
 				refresh_delay = m_refresh_interval ;
+#ifdef FLDIGI_KML_CONDITION_VARIABLE
 			} else {
 				refresh_delay = tmp_tim.tv_sec - time(NULL);
 				if( refresh_delay <= 0 ) refresh_delay = 1 ;
 				// LOG_INFO("Interrupted when waiting. Restart with wait=%d", refresh );
+#endif
 			}
 		} // Endless loop.
 		return NULL ;
@@ -1494,7 +1549,7 @@ public:
 		}
 
 		// Now the object is usable. Theoretically should be protected by a mutex.
-		LOG_INFO("Object ready");
+		LOG_DEBUG("Object ready");
 
 		/// Even if an exception was thrown when loading the previous file, it does not 
 		/// prevent to overwrite the old files with new and clean ones.
@@ -1510,8 +1565,13 @@ public:
 	, m_refresh_interval(-1)
 	, m_balloon_style(0)
 	{
-		LOG_INFO("Creation");
+		LOG_DEBUG("Creation");
+#ifdef FLDIGI_KML_CONDITION_VARIABLE
 		pthread_cond_init( &m_cond_queue, NULL );
+#else
+		m_bool_queue = false;
+		m_kml_must_leave = false;
+#endif
 		pthread_mutex_init( &m_mutex_write, NULL );
 
 		/// TODO: Add this thread to the other fldigi threads stored in cbq[].
@@ -1553,7 +1613,11 @@ public:
 			LOG_ERROR("Category %s undefined", category.c_str());
 		}
 		ptrMap->Enqueue( tmpKmlNam, currPM );
+#ifdef FLDIGI_KML_CONDITION_VARIABLE
 		pthread_cond_signal( &m_cond_queue );
+#else
+		m_bool_queue = true;
+#endif
 		LOG_INFO("'%s' sz=%d time=%s nb_broad=%d m_merge_dist=%lf",
 			descrTxt.c_str(), (int)ptrMap->size(),
 			KmlTimestamp(evtTim).c_str(),
@@ -1567,12 +1631,17 @@ public:
 			LOG_INFO("Cancelling writer thread");
 			guard_lock myGuard( &m_mutex_write );
 
+#ifdef FLDIGI_KML_CONDITION_VARIABLE
 			LOG_INFO("Cancelling subthread");
 			int r = pthread_cancel( m_writer_thread );
 			if( r ) {
 				LOG_ERROR("pthread_cancel %s", strerror(errno) );
 				return ;
 			}
+#else
+			LOG_INFO("Setting exit flag.");
+			m_kml_must_leave = true ;
+#endif
 		}
 		// LOG_INFO("Joining subthread");
 		void * retPtr;
@@ -1592,7 +1661,9 @@ public:
 		/// Here we are sure that the subthread is stopped. The subprocess is not called.
 		RewriteKmlFileFull();
 
+#ifdef FLDIGI_KML_CONDITION_VARIABLE
 		pthread_cond_destroy( &m_cond_queue );
+#endif
 		pthread_mutex_destroy( &m_mutex_write );
 	}