Index: XIOS3/trunk/src/transport/p2p_client_buffer.cpp
===================================================================
--- XIOS3/trunk/src/transport/p2p_client_buffer.cpp	(revision 2593)
+++ XIOS3/trunk/src/transport/p2p_client_buffer.cpp	(revision 2594)
@@ -41,4 +41,5 @@
     //}
     currentWindow_=-1 ;
+    currentMirror_=-1 ;
     
     //MPI_Win_create_dynamic(MPI_INFO_NULL, winComm_, &winControl_);
@@ -59,11 +60,12 @@
   void CP2pClientBuffer::newBuffer(size_t size, bool fixed)
   { 
+    currentMirror_++;
     currentWindow_=(currentWindow_+1)%maxWindows_ ;
-    if (usedWindows_[currentWindow_]) 
-    {
-      ERROR("void CP2pClientBuffer::newBuffer(size_t size, bool fixed)",<<"Try to alloc buffer to a window already in use"<<endl ) ;
-    }
-    else usedWindows_[currentWindow_]=true ;
-    buffers_.push_back(new CBuffer(windows_[currentWindow_], size, fixed)); 
+    //if (usedWindows_[currentWindow_]) 
+    //{
+    //  ERROR("void CP2pClientBuffer::newBuffer(size_t size, bool fixed)",<<"Try to alloc buffer to a window already in use"<<endl ) ;
+    //}
+    //else usedWindows_[currentWindow_]=true ;
+    buffers_.push_back(new CBuffer(windows_[currentMirror_], size, fixed)); 
     currentBuffer_=buffers_.back() ;
     info(logProtocol)<<"   Nb attached memory blocs="<<buffers_.size()<<endl ;
@@ -106,5 +108,8 @@
         if (buffers_.empty())
         {
-          if (fixed_) newBuffer(fixedSize_,fixed_) ;
+          if (fixed_) {
+            currentBufferSize_=fixedSize_;
+            newBuffer(fixedSize_,fixed_) ;
+          }
           else
           { 
@@ -119,5 +124,6 @@
         if (count > 0) 
         {
-          blocs_.push_back({addr,currentBuffer_, start, static_cast<int>(count), currentWindow_}) ;
+          //info(logProtocol) << "Using currentMirror_ 1 : "<<currentMirror_ << endl;
+          blocs_.push_back({addr,currentBuffer_, start, static_cast<int>(count), currentMirror_}) ;
           nbBlocs++ ; 
         }
@@ -128,5 +134,6 @@
         if (count > 0) 
         {
-          blocs_.push_back({addr,currentBuffer_, start, static_cast<int>(count), currentWindow_}) ;
+          //info(logProtocol) << "Using currentMirror_ 2 : "<<currentMirror_ << endl;
+          blocs_.push_back({addr,currentBuffer_, start, static_cast<int>(count), currentMirror_}) ;
           nbBlocs++ ; 
         }
@@ -181,5 +188,5 @@
       if (buffers_.size()>1) 
       {  
-        usedWindows_[bloc.window]=false ;
+        //usedWindows_[bloc.window]=false ;
         delete buffers_.front() ;
         buffers_.pop_front() ;
@@ -279,5 +286,5 @@
     ostringstream outStr ;
     SRequest request ;
-    request.buffer = new CBufferOut(sizeof(timeline)+sizeof(nbSenders)+sizeof(nbBlocs)+(sizeof(MPI_Aint)+sizeof(int)+sizeof(int))*nbBlocs) ; 
+    request.buffer = new CBufferOut(sizeof(timeline)+sizeof(nbSenders)+sizeof(nbBlocs)+(sizeof(MPI_Aint)+sizeof(int)+sizeof(int)+sizeof(size_t))*nbBlocs) ; 
     *(request.buffer)<<timeline<<nbSenders<<nbBlocs ;
     if (info.isActive(logProtocol))  outStr<<"New timeline event sent to server rank "<<serverRank_<<" : timeLine="<<timeline<<"  nbSenders="<<nbSenders<<"  nbBlocs="<<nbBlocs<<endl ;
@@ -286,5 +293,5 @@
     for(int i=0 ; i<nbBlocs; ++i,++it) 
     {
-      *(request.buffer) << it->addr << it->count << it->window;
+      *(request.buffer) << it->addr << it->count << it->window << it->start;
     
       if (info.isActive(logProtocol))
@@ -292,5 +299,5 @@
         size_t checksum=0 ;
         for(size_t j=0;j<it->count;j++) checksum+=((unsigned char*)(it->addr))[j] ;
-        outStr<<"Bloc "<<i<<"  addr="<<it->addr<<"  count="<<it->count<<"  checksum="<<checksum<<"  ;  " ;
+        outStr<<"Bloc "<<i<<"  addr="<<it->addr<<"  count="<<it->count<<"  checksum="<<checksum<<"  window="<<it->window<<"  start="<<it->start<<"  ;  " ;
       }
 
@@ -300,4 +307,5 @@
     }
     if (info.isActive(logProtocol)) CTimer::get("sendTimelineEvent : MPI_Isend").resume() ;
+    //info(logProtocol) << "Send event : " << request.buffer->count() << endl;
     MPI_Isend(request.buffer->start(),request.buffer->count(), MPI_CHAR, intraServerRank_, 20, interCommMerged_, &request.mpiRequest ) ;
     if (info.isActive(logProtocol)) CTimer::get("sendTimelineEvent : MPI_Isend").suspend() ;
@@ -311,4 +319,5 @@
     request.buffer = new CBufferOut(sizeof(EVENT_BUFFER_RESIZE)+sizeof(timeline)+sizeof(size)) ; 
     *(request.buffer)<<EVENT_BUFFER_RESIZE<<timeline<<size ;
+    //info(logProtocol) << "Send resize : " << request.buffer->count() << endl;
     MPI_Isend(request.buffer->start(),request.buffer->count(), MPI_CHAR, intraServerRank_, 20, interCommMerged_, &request.mpiRequest ) ;
     requests_.push_back(request) ;
Index: XIOS3/trunk/src/transport/p2p_client_buffer.hpp
===================================================================
--- XIOS3/trunk/src/transport/p2p_client_buffer.hpp	(revision 2593)
+++ XIOS3/trunk/src/transport/p2p_client_buffer.hpp	(revision 2594)
@@ -53,4 +53,5 @@
             if (start_-end_ >= size)
             {
+              //info(logProtocol)<<" CASE 0 : start/end/count - size : "<< start_ << ", " << end_ << ", " << count_ << " " << size_ << " vs size " << size << endl;
               count=size ;
               size = 0 ;
@@ -64,4 +65,5 @@
             else
             {
+              //info(logProtocol)<<" CASE 1 : start/end/count - size : "<< start_ << ", " << end_ << ", " << count_ << " " << size_ << " vs size " << size << endl;
               count = start_-end_ ;
               size -= count ;
@@ -78,4 +80,5 @@
             if (size_-end_ >= size)
             {
+              //info(logProtocol)<<" CASE 2 : start/end/count - size : "<< start_ << ", " << end_ << ", " << count_ << " " << size_ << " vs size " << size << endl;
               count = size ;
               size = 0;
@@ -89,4 +92,5 @@
             else
             {
+              //info(logProtocol)<<" CASE 3 : start/end/count - size : "<< start_ << ", " << end_ << ", " << count_ << " " << size_ << " vs size " << size << endl;
               count = size_ - end_ ;
               size -= count ;
@@ -185,4 +189,5 @@
       vector<bool> usedWindows_ ;
       int currentWindow_ ;
+      int currentMirror_ ;
       int maxWindows_ ;
 
Index: XIOS3/trunk/src/transport/p2p_server_buffer.cpp
===================================================================
--- XIOS3/trunk/src/transport/p2p_server_buffer.cpp	(revision 2593)
+++ XIOS3/trunk/src/transport/p2p_server_buffer.cpp	(revision 2594)
@@ -19,4 +19,5 @@
     //bufferIn >> controlAddr_;
     createWindow(commSelf, interCommMerged) ;
+    countDeletedBuffers_ = 0;
   }
 
@@ -80,4 +81,5 @@
       int count ;
       int window ;
+      size_t start ; 
       bufferIn >> nbBlocs ;
       MPI_Aint bloc ;
@@ -85,6 +87,7 @@
       for(int i=0;i<nbBlocs;++i) 
       {
-        bufferIn >> bloc >> count >> window;
-        blocs.push_back({bloc, count, window}) ;
+        bufferIn >> bloc >> count >> window >> start;
+        //info(logProtocol) << "Receiving window : "<<window << endl;
+        blocs.push_back({bloc, count, window,start}) ;
       }
     }
@@ -115,6 +118,10 @@
     {
       if (buffers_.front()->getCount()==0) {
+        // If the front buffer is empty and if another buffer become the active one (buffers_.size()>1)
+        //     the front buffer can be deleted, no new message will be sent through the front buffer
         delete buffers_.front();
-        buffers_.pop_front() ; // if buffer is empty free buffer
+        buffers_.erase(buffers_.begin()) ; // if buffer is empty free buffer
+        //info(logProtocol) << "Deleting win : " << countDeletedBuffers_  << endl;
+        countDeletedBuffers_++;
       }
     }
@@ -223,4 +230,15 @@
     }
   }
+  
+  size_t CP2pServerBuffer::remainSize(int bufferId)
+  {
+    if (bufferId-countDeletedBuffers_>=buffers_.size())
+    {
+      //info(logProtocol) << "The buffer " << bufferId << " is not yet allocated" << endl;
+      return 0;
+    }      
+    return buffers_[bufferId-countDeletedBuffers_]->remain() ;
+  }
+
 
   void CP2pServerBuffer::transferEvents(void)
@@ -232,29 +250,12 @@
 
       size_t timeline =  pendingBlocs_.begin()->first ;
-      auto& blocs = pendingBlocs_.begin()->second ;
-      
-      if (!bufferResize_.empty()) 
-      {
-        if (bufferResize_.front().first==timeline)
-        {
-          currentBufferSize_=bufferResize_.front().second * bufferServerFactor_ ;
-          info(logProtocol)<<"Received new buffer size="<<currentBufferSize_<<"  at timeline="<<timeline<<endl ;
-          bufferResize_.pop_front() ;
-          newBuffer(currentBufferSize_,fixed_) ;
-        }
-      }
+      auto& blocs = pendingBlocs_.begin()->second ; // map<size_t  , list<tuple<MPI_Aint,int ,int,size_t>>> pendingBlocs_;
+                                                    //     timeline,            addr    ,size,win,start
+      // addr   = std::get<0>(bloc) ;
+      // size   = std::get<1>(bloc) ;
+      // window = std::get<2>(bloc) ;
+      // start  = std::get<3>(bloc) ; // start : used to check mirror behavior
 
       size_t eventSize=0 ;
-      for(auto& bloc : blocs) eventSize+=get<1>(bloc) ;
-      
-      if (eventSize > remain) 
-      {
-        if ( eventSize <= currentBufferSize_) return ; // wait for free storage ;
-        else 
-        {
-          if (currentBuffer_==nullptr) remain = eventSize ;
-          else remain = currentBuffer_->remain() + fixedSize_ ;
-        }
-      }
       
       //if (isLocked_) ERROR("void COneSidedServerBuffer::transferEvents(void)",<<"windows is Locked");
@@ -275,5 +276,44 @@
       //}
       //isLocked_=true ;
-      do
+//      do
+
+      bool spaceForAllblocks = true;
+      int lastBufferUsed = -1;
+      if (blocs.size()==0) spaceForAllblocks = false;
+      else
+      {
+        for(auto& bloc : blocs)
+        {
+          //info(logProtocol) << "blocSize = " << get<1>(bloc)
+          //                  << " - remain in win : " << get<2>(bloc) << " : " << remainSize( get<2>(bloc) )
+          //                  << "; bufferResize_ = " <<  bufferResize_.size() << endl;
+          
+          // if the active buffer change, the new buffer must be considered as empty
+          if (lastBufferUsed != get<2>(bloc) ) eventSize = 0;
+
+          // if the targeted buffer does not exist
+          if ( get<2>(bloc)-countDeletedBuffers_>=buffers_.size() )
+          {
+            if ( bufferResize_.empty() ) // no resize order
+            {
+              spaceForAllblocks = false;
+              break;
+            }
+          }
+          else if ( ( get<1>(bloc) > (remainSize(get<2>(bloc))-eventSize) ) )  // if there is no enough place in the targeted bloc
+          {
+            spaceForAllblocks = false;
+            break;
+          }
+          else
+          {
+            // if there is enough place in the targeted bloc, store the 
+            lastBufferUsed = get<2>(bloc);
+            eventSize += get<1>(bloc);
+          }
+        }
+      }      
+
+      if (spaceForAllblocks)
       {
         transferEvent() ; // ok enough storage for this bloc
@@ -284,22 +324,12 @@
         //  break ; // transfering just one event temporary => to remove
         
-        if (pendingBlocs_.empty()) break ; // no more blocs to tranfer => exit loop
-
-        timeline =  pendingBlocs_.begin()->first ;
-        auto& blocs=pendingBlocs_.begin()->second ;
-        
-        if (!bufferResize_.empty()) 
-        {
-          if (bufferResize_.front().first==timeline)
-          {
-            currentBufferSize_=bufferResize_.front().second * bufferServerFactor_ ;
-            info(logProtocol)<<"Received new buffer size="<<currentBufferSize_<<"  at timeline="<<timeline<<endl ;
-            bufferResize_.pop_front() ;
-            newBuffer(currentBufferSize_,fixed_) ;
-          }
-        }
-
-        for(auto& bloc : blocs) eventSize+=get<1>(bloc) ;
-        if (transferedSize+eventSize<=remain)
+//        if (pendingBlocs_.empty()) break ; // no more blocs to tranfer => exit loop
+//
+//        timeline =  pendingBlocs_.begin()->first ;
+//        auto& blocs=pendingBlocs_.begin()->second ;
+//        
+//
+//        for(auto& bloc : blocs) eventSize+=get<1>(bloc) ;
+//        if (transferedSize+eventSize<=remain)
         {
           //for(auto& bloc : blocs) 
@@ -317,5 +347,5 @@
         }
       }
-      while(transferedSize+eventSize<=remain) ;
+//      while(transferedSize+eventSize<=remain) ;
       
     }
@@ -341,36 +371,38 @@
       size = std::get<1>(bloc) ;
       window = std::get<2>(bloc) ;
+      start = std::get<3>(bloc) ; // start : used to check mirror behavior
 
       offset=0 ;
 
+      // Need to keep loop even if a given bloc will not be split.
+      // To mimic client behavior, especially if (size_==end_) reset end_ = 0 ;
       do
       {
-        if (currentBuffer_!=nullptr)
-        {
-          currentBuffer_->reserve(size, start, count) ;
+        //if ( (currentBuffer_!=nullptr) || (window-countDeletedBuffers_ == buffers_.size() ) )
+        {
+          if (window-countDeletedBuffers_ >= buffers_.size())
+            {
+              if (!bufferResize_.empty()) 
+                {
+                  if (bufferResize_.front().first==timeline)
+                    {
+                      currentBufferSize_=bufferResize_.front().second * bufferServerFactor_ ;
+                      //info(logProtocol)<<"Received new buffer size="<<currentBufferSize_<<"  at timeline="<<timeline<<endl ;
+                      bufferResize_.pop_front() ;
+                      newBuffer(currentBufferSize_,fixed_) ;
+                    }
+                }
+            }
+          
+          buffers_[window-countDeletedBuffers_]->reserve(size, start, count) ;
       
           if ( count > 0)
           {
-            transferRmaRequest(timeline, addr, offset, currentBuffer_, start, count, window) ;
+            transferRmaRequest(timeline, addr, offset, buffers_[window-countDeletedBuffers_], start, count, window) ;
             offset=MPI_Aint_add(offset, count) ;
-          }
-          //currentBuffer_->reserve(size, start, count) ;
-      
-          //if ( count > 0)
-          //{
-          //  transferRmaRequest(timeline, addr, offset, currentBuffer_, start, count, window) ;
-          //  offset=MPI_Aint_add(offset, count) ;
-          //}
+            
+          }
         }
 
-        if (size>0) 
-        {
-          if (fixed_) newBuffer(std::max(fixedSize_, size),fixed_) ;
-          else
-          {
-            currentBufferSize_ = std::max((size_t)(currentBufferSize_*growingFactor_), size) ;
-            newBuffer(currentBufferSize_,fixed_) ;
-          }
-        }
       } while (size > 0 ) ;
     }
@@ -385,5 +417,5 @@
     if (info.isActive(logProtocol))
     {
-      info(logProtocol)<<"receive Bloc from client "<<clientRank_<<" : timeline="<<timeline<<"  addr="<<addr<<"  count="<<count<<" buffer="<<buffer<<"  start="<<start<<endl ;
+      info(logProtocol)<<"receive Bloc from client "<<clientRank_<<" : timeline="<<timeline<<"  addr="<<addr<<"  count="<<count<<" buffer="<<buffer<<"  start="<<start<<"  window="<<window<<endl ;
       info(logProtocol)<<"check dest buffers ; start_buffer="<<static_cast<void*>(buffer->getBuffer())<<"  end_buffer="<<static_cast<void*>(buffer->getBuffer()+buffer->getSize()-1)
                <<"  start="<<static_cast<void*>(buffer->getBuffer()+start)<<"   end="<<static_cast<void*>(buffer->getBuffer()+start+count-1)<<endl ;
@@ -425,4 +457,5 @@
 
       size+=bloc.count ;
+      //info(logProtocol) << "Free from : " << bloc.start << ", size : " << bloc.count<< endl;
       bloc.buffer->free(bloc.start, bloc.count) ; // free bloc
       addr=bloc.addr ;
@@ -431,6 +464,10 @@
         if (buffers_.size() > 1)
         {
+          // If the front buffer is empty and if another buffer become the active one (buffers_.size()>1)
+          //     the front buffer can be deleted, no new message will be sent through the front buffer
           delete buffers_.front();
-          buffers_.pop_front() ; // if buffer is empty free buffer
+          buffers_.erase(buffers_.begin()) ; // if buffer is empty free buffer
+          //info(logProtocol) << "Deleting win : " << countDeletedBuffers_  << endl;
+          countDeletedBuffers_++;
         }
       }
Index: XIOS3/trunk/src/transport/p2p_server_buffer.hpp
===================================================================
--- XIOS3/trunk/src/transport/p2p_server_buffer.hpp	(revision 2593)
+++ XIOS3/trunk/src/transport/p2p_server_buffer.hpp	(revision 2594)
@@ -46,4 +46,5 @@
               if (start_-end_ >= size)
               {
+                //if (start!=end_) info(logProtocol)<<" CASE 0, recv/computed : " << start << "/" << end_ << endl;
                 count=size ;
                 size = 0 ;
@@ -54,4 +55,8 @@
               else
               {
+		// Server buffers get blocs from clients, they should not be splitted (mirrors the client buffers)
+                //if (start!=end_) info(logProtocol)<<" CASE 1"<< endl;
+                //info(logProtocol)<<" CASE 1 : start/end/count - size : "<< start_ << ", " << end_ << ", " << count_ << " " << size_ << " vs size " << size << endl;
+                ERROR("COneSidedServerBuffer::reserve()",<<"This should be the case of the 2nd part of a splitted message"<<std::endl);
                 //count = start_-end_ ;
                 //size -= count ;
@@ -66,4 +71,5 @@
               if (size_-end_ >= size)
               {
+                //if (start!=end_ ) info(logProtocol)<<" CASE 2, recv/computed : "<< start << "/" << end_ << endl;
                 count = size ;
                 size = 0;
@@ -74,8 +80,13 @@
               else
               {
+                // Server buffers get blocs from clients, they should not be splitted (mirrors the client buffers)
+                //     1st part of a splitted message, fill the end of the buffer
+                //     end_ must be set to 0 like on clients
+                //if (start!=end_) info(logProtocol)<<" CASE 3"<< endl;
+                //  info(logProtocol)<<" CASE 3 : start/end/count - size : "<< start_ << ", " << end_ << ", " << count_ << " " << size_ << " vs size " << size << endl;
                 //count = size_ - end_ ;
                 //size -= count ;
                 //start=end_ ;
-                //end_ = 0 ;
+                end_ = 0 ;
                 //count_+= count ;
                 count = 0 ;
@@ -94,5 +105,12 @@
           }
 
-          size_t remain(void) { return size_-count_; }
+          size_t remain(void) {
+            if (count_==0)
+              return size_;
+            else if (end_<start_)
+              return start_-end_;
+            else
+              return size_-end_;
+          }
           size_t getSize(void) { return size_ ;}
           size_t getCount(void) {return count_ ;}
@@ -110,5 +128,6 @@
           while (!buffers_.empty()) {
               delete buffers_.front();
-              buffers_.pop_front() ; // if buffer is empty free buffer
+              buffers_.erase(buffers_.begin()) ; // if buffer is empty free buffer
+              countDeletedBuffers_++;
           }
       };
@@ -135,4 +154,5 @@
       void transferRmaRequest(size_t timeline, MPI_Aint addr, MPI_Aint offset, CBuffer* buffer, size_t start, int count, int window) ;
       size_t remainSize(void) ;
+      size_t remainSize(int bufferId) ;
 
 
@@ -144,5 +164,5 @@
       double bufferServerFactor_=1. ;
       
-      std::list<CBuffer*> buffers_ ;
+      std::vector<CBuffer*> buffers_ ;
       CBuffer* currentBuffer_=nullptr ;
 
@@ -151,5 +171,5 @@
 
       map<size_t, int> nbSenders_ ;
-      map<size_t, list<tuple<MPI_Aint,int,int>>> pendingBlocs_;
+      map<size_t, list<tuple<MPI_Aint,int,int,size_t>>> pendingBlocs_;
      
       vector<MPI_Request> pendingRmaRequests_ ;
@@ -176,4 +196,5 @@
       const int windowRank_=0 ;
       MPI_Aint lastBlocToFree_=0 ;
+      int countDeletedBuffers_;
 
   } ;
