Masanobu Yasui authored on 2008/11/20 18:23:15
Showing 8 changed files
... ...
@@ -1,3 +1,8 @@
1
+1.0.1:
2
+ - add spec file   (support/makuosan.spec)
3
+ - add init script (support/makuosan.sysv)
4
+ - support for FreeBSD & MacOSX
5
+
1 6
 1.0.0:
2 7
  - stable release
3 8
  - change default value -f option. 1 to 3
... ...
@@ -39,7 +39,6 @@ char *rstatestrlist[16] = {"RECV_NONE",
39 39
                            "RECV_CLOSE",
40 40
                            "RECV_IGNORE",
41 41
                            "RECV_READONLY",
42
-                           "RECV_RETRY",
43 42
                            "RECV_MD5OK",
44 43
                            "RECV_MD5NG",
45 44
                            "RECV_OPENERR",
... ...
@@ -56,7 +55,6 @@ uint8_t rstatenumlist[16]={MAKUO_RECVSTATE_NONE,
56 56
                            MAKUO_RECVSTATE_CLOSE,
57 57
                            MAKUO_RECVSTATE_IGNORE,
58 58
                            MAKUO_RECVSTATE_READONLY,
59
-                           MAKUO_RECVSTATE_RETRY,
60 59
                            MAKUO_RECVSTATE_MD5OK,
61 60
                            MAKUO_RECVSTATE_MD5NG,
62 61
                            MAKUO_RECVSTATE_OPENERROR,
... ...
@@ -358,15 +356,15 @@ int seq_addmark(mfile *m, uint32_t lseq, uint32_t useq)
358 358
     }
359 359
   }
360 360
   size = m->marksize;
361
-  while(size < m->markcount + useq - lseq)
361
+  while(size < m->markcount + useq - lseq){
362 362
     size += 1024;
363
+  }
363 364
   if(size != m->marksize){
364 365
     n = realloc(m->mark, sizeof(uint32_t) * size);
365 366
     if(!n){
366 367
       lprintf(0, "%s: out of memory(realloc)\n", __func__);
367 368
       return(-1); 
368 369
     }
369
-    a = mfins(0);
370 370
     m->mark = n;
371 371
     m->marksize = size;
372 372
   }
... ...
@@ -378,19 +376,13 @@ int seq_addmark(mfile *m, uint32_t lseq, uint32_t useq)
378 378
         break;
379 379
     if(j == m->markcount){
380 380
       m->mark[m->markcount++] = i;
381
+      m->markdelta++;
381 382
     }
382 383
   }
383
-
384
-  /***** complaint *****/
385
-  if(a){
386
-    lprintf(2,"%s: complaint (%d/%d) %s\n", __func__, m->markcount, m->marksize, m->fn);
387
-    a->mdata.head.flags |= MAKUO_FLAG_ACK;
388
-    a->mdata.head.opcode = m->mdata.head.opcode;
389
-    a->mdata.head.reqid  = m->mdata.head.reqid;
390
-    a->mdata.head.szdata = 0;
391
-    a->mdata.head.seqno  = m->mdata.head.seqno;
392
-    a->mdata.head.nstate = MAKUO_RECVSTATE_RETRY;
393
-    memcpy(&(a->addr), &(m->addr), sizeof(a->addr));
384
+  lprintf(1,"%s: l=%u u=%u sub=%d\n", __func__, lseq, useq, useq - lseq);
385
+  if(m->markdelta>64){
386
+    m->markdelta = 0;
387
+    return(1);
394 388
   }
395 389
   return(0);
396 390
 }
... ...
@@ -1,6 +1,6 @@
1 1
 #! /bin/sh
2 2
 # Guess values for system-dependent variables and create Makefiles.
3
-# Generated by GNU Autoconf 2.61 for makuosan 1.0.1.
3
+# Generated by GNU Autoconf 2.61 for makuosan 1.0.2.
4 4
 #
5 5
 # Report bugs to <info-makuosan@klab.jp>.
6 6
 #
... ...
@@ -574,8 +574,8 @@ SHELL=${CONFIG_SHELL-/bin/sh}
574 574
 # Identity of this package.
575 575
 PACKAGE_NAME='makuosan'
576 576
 PACKAGE_TARNAME='makuosan'
577
-PACKAGE_VERSION='1.0.1'
578
-PACKAGE_STRING='makuosan 1.0.1'
577
+PACKAGE_VERSION='1.0.2'
578
+PACKAGE_STRING='makuosan 1.0.2'
579 579
 PACKAGE_BUGREPORT='info-makuosan@klab.jp'
580 580
 
581 581
 ac_unique_file="makuosan.c"
... ...
@@ -1209,7 +1209,7 @@ if test "$ac_init_help" = "long"; then
1209 1209
   # Omit some internal or obsolete options to make the list less imposing.
1210 1210
   # This message is too long to be a string in the A/UX 3.1 sh.
1211 1211
   cat <<_ACEOF
1212
-\`configure' configures makuosan 1.0.1 to adapt to many kinds of systems.
1212
+\`configure' configures makuosan 1.0.2 to adapt to many kinds of systems.
1213 1213
 
1214 1214
 Usage: $0 [OPTION]... [VAR=VALUE]...
1215 1215
 
... ...
@@ -1275,7 +1275,7 @@ fi
1275 1275
 
1276 1276
 if test -n "$ac_init_help"; then
1277 1277
   case $ac_init_help in
1278
-     short | recursive ) echo "Configuration of makuosan 1.0.1:";;
1278
+     short | recursive ) echo "Configuration of makuosan 1.0.2:";;
1279 1279
    esac
1280 1280
   cat <<\_ACEOF
1281 1281
 
... ...
@@ -1359,7 +1359,7 @@ fi
1359 1359
 test -n "$ac_init_help" && exit $ac_status
1360 1360
 if $ac_init_version; then
1361 1361
   cat <<\_ACEOF
1362
-makuosan configure 1.0.1
1362
+makuosan configure 1.0.2
1363 1363
 generated by GNU Autoconf 2.61
1364 1364
 
1365 1365
 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
... ...
@@ -1373,7 +1373,7 @@ cat >config.log <<_ACEOF
1373 1373
 This file contains any messages produced by compilers while
1374 1374
 running configure, to aid debugging if configure makes a mistake.
1375 1375
 
1376
-It was created by makuosan $as_me 1.0.1, which was
1376
+It was created by makuosan $as_me 1.0.2, which was
1377 1377
 generated by GNU Autoconf 2.61.  Invocation command line was
1378 1378
 
1379 1379
   $ $0 $@
... ...
@@ -2064,7 +2064,7 @@ fi
2064 2064
 
2065 2065
 # Define the identity of the package.
2066 2066
  PACKAGE='makuosan'
2067
- VERSION='1.0.1'
2067
+ VERSION='1.0.2'
2068 2068
 
2069 2069
 
2070 2070
 cat >>confdefs.h <<_ACEOF
... ...
@@ -8995,7 +8995,7 @@ exec 6>&1
8995 8995
 # report actual input values of CONFIG_FILES etc. instead of their
8996 8996
 # values after options handling.
8997 8997
 ac_log="
8998
-This file was extended by makuosan $as_me 1.0.1, which was
8998
+This file was extended by makuosan $as_me 1.0.2, which was
8999 8999
 generated by GNU Autoconf 2.61.  Invocation command line was
9000 9000
 
9001 9001
   CONFIG_FILES    = $CONFIG_FILES
... ...
@@ -9052,7 +9052,7 @@ Report bugs to <bug-autoconf@gnu.org>."
9052 9052
 _ACEOF
9053 9053
 cat >>$CONFIG_STATUS <<_ACEOF
9054 9054
 ac_cs_version="\\
9055
-makuosan config.status 1.0.1
9055
+makuosan config.status 1.0.2
9056 9056
 configured by $0, generated by GNU Autoconf 2.61,
9057 9057
   with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
9058 9058
 
... ...
@@ -1,7 +1,7 @@
1 1
 #                                               -*- Autoconf -*-
2 2
 # Process this file with autoconf to produce a configure script.
3 3
 AC_PREREQ(2.61)
4
-AC_INIT(makuosan, 1.0.1, info-makuosan@klab.jp)
4
+AC_INIT(makuosan, 1.0.2, info-makuosan@klab.jp)
5 5
 AM_INIT_AUTOMAKE
6 6
 AC_CONFIG_SRCDIR([makuosan.c])
7 7
 AC_CONFIG_HEADER([config.h])
... ...
@@ -56,7 +56,7 @@
56 56
 /*----- timeout -----*/
57 57
 #define MAKUO_SEND_TIMEOUT  500    /* 再送間隔(ms)                                 */
58 58
 #define MAKUO_SEND_RETRYCNT 120    /* 再送回数                                     */
59
-#define MAKUO_SEND_DELAYSTP 1      /* 送出遅延時間の増分(ms)                       */
59
+#define MAKUO_SEND_DELAYSTP 0      /* 送出遅延時間の増分(ms)                       */
60 60
 #define MAKUO_PONG_TIMEOUT  180000 /* メンバから除外するまでの時間(ms)             */
61 61
 #define MAKUO_PONG_INTERVAL 45000  /* PING送信間隔(ms)                             */
62 62
 #define MAKUO_RECV_GCWAIT   180000 /* 消し損ねたオブジェクトを開放する待ち時間(ms) */
... ...
@@ -70,6 +70,8 @@
70 70
 /*----- flags -----*/
71 71
 #define MAKUO_FLAG_ACK   1
72 72
 #define MAKUO_FLAG_CRYPT 2
73
+#define MAKUO_FLAG_WAIT  4
74
+#define MAKUO_FLAG_FMARK 8
73 75
 
74 76
 /*----- sendstatus -----*/
75 77
 #define MAKUO_SENDSTATE_STAT       0  /* 更新確認待 */
... ...
@@ -90,7 +92,6 @@
90 90
 #define MAKUO_RECVSTATE_CLOSE      5
91 91
 #define MAKUO_RECVSTATE_IGNORE     6
92 92
 #define MAKUO_RECVSTATE_READONLY   7
93
-#define MAKUO_RECVSTATE_RETRY      8
94 93
 #define MAKUO_RECVSTATE_MD5OK      10
95 94
 #define MAKUO_RECVSTATE_MD5NG      11
96 95
 #define MAKUO_RECVSTATE_OPENERROR  90
... ...
@@ -190,8 +191,12 @@ typedef struct
190 190
   uint32_t senddelay;
191 191
   uint32_t initstate;
192 192
   uint32_t recvcount;
193
+  uint32_t markdelta;
193 194
   uint32_t markcount;
195
+  uint32_t waitcount;
196
+  uint32_t waitspan;
194 197
   uint32_t marksize;
198
+  uint32_t seqnonow;
195 199
   uint32_t seqnomax;
196 200
   mdata mdata;
197 201
   mcomm *comm;
... ...
@@ -331,6 +331,7 @@ int mexec_send(mcomm *c, int n)
331 331
 	m->comm      = c;
332 332
   m->dryrun    = (mode == MAKUO_MEXEC_DRY);
333 333
   m->initstate = 1;
334
+  m->seqnonow  = 0;
334 335
   m->seqnomax  = m->fs.st_size / MAKUO_BUFFER_SIZE;
335 336
   if(m->fs.st_size % MAKUO_BUFFER_SIZE){
336 337
     m->seqnomax++; 
... ...
@@ -615,15 +616,17 @@ int mexec_status(mcomm *c, int n)
615 615
     cprintf(0, c, "basedir  : %s/\n", moption.base_dir);
616 616
   }
617 617
   count = 0;
618
-  for(m=mftop[0];m;m=m->next)
618
+  for(m=mftop[0];m;m=m->next){
619 619
     count++;
620
+  }
620 621
   cprintf(0,c,"send file: %d\n", count);
621 622
   for(m=mftop[0];m;m=m->next){
622
-    if(m->lickflag){
623
-      cprintf(0, c, "  %s %s (%d/%d)\n", SSTATE(m->mdata.head.nstate), m->fn, m->mdata.head.seqno,m->seqnomax); 
624
-    }else{
625
-      cprintf(0, c, "  %s %s (%d/%d)\n", SSTATE(m->mdata.head.nstate), m->fn, m->mdata.head.seqno,m->seqnomax); 
623
+    uint32_t snow = m->seqnonow;
624
+    uint32_t smax = m->seqnomax;
625
+    if(snow > smax){
626
+      snow = smax;
626 627
     }
628
+    cprintf(0, c, "  %s %s (%u:%u/%u)\n", SSTATE(m->mdata.head.nstate), m->fn, m->markcount, snow, smax); 
627 629
   }
628 630
 
629 631
   count = 0;
... ...
@@ -209,6 +209,20 @@ static void mrecv_ack_ping(mdata *data, struct sockaddr_in *addr)
209 209
   member_add(&addr->sin_addr, data);
210 210
 }
211 211
 
212
+static void mrecv_ack_send_mark(mdata *data, mfile *m, mhost *t)
213
+{
214
+  uint32_t *d = (uint32_t *)(data->data);
215
+  while(d < (uint32_t *)&data->data[data->head.szdata]){
216
+    if(*d >= m->seqnomax){
217
+      lprintf(0, "%s: mark seqno error seq=%d max=%d %s from %s\n", __func__,
218
+         *d, m->seqnomax, m->fn, t->hostname);
219
+      break;
220
+    }
221
+    seq_addmark(m, *d, (*d) + 1);
222
+    d++;
223
+  }
224
+}
225
+
212 226
 static void mrecv_ack_send(mdata *data, struct sockaddr_in *addr)
213 227
 {
214 228
   uint8_t *r;
... ...
@@ -224,31 +238,22 @@ static void mrecv_ack_send(mdata *data, struct sockaddr_in *addr)
224 224
       data->head.reqid, RSTATE(data->head.nstate), inet_ntoa(t->ad), t->hostname, m->fn);
225 225
   }
226 226
   if(data->head.nstate == MAKUO_RECVSTATE_MARK){
227
-    uint32_t *d = (uint32_t *)(data->data);
228
-    while(d < (uint32_t *)&data->data[data->head.szdata]){
229
-      if(*d >= m->seqnomax){
230
-        lprintf(0, "%s: mark seqno error seq=%d max=%d %s from %s\n", __func__,
231
-           *d, m->seqnomax, m->fn, t->hostname);
232
-        break;
233
-      }
234
-      seq_addmark(m, *d, (*d) + 1);
235
-      d++;
227
+    mrecv_ack_send_mark(data, m, t);
228
+    if(data->head.flags & MAKUO_FLAG_FMARK){
229
+      return;
236 230
     }
237 231
   }
238
-  if(data->head.nstate == MAKUO_RECVSTATE_RETRY){
239
-    lprintf(0, "%s: send retry %s from %s\n", __func__, m->fn, t->hostname);
240
-    m->sendwait   = 0;
241
-    m->lickflag   = 0;
242
-    m->senddelay += MAKUO_SEND_DELAYSTP;
243
-    m->mdata.head.seqno  = 0;
244
-    m->mdata.head.nstate = MAKUO_SENDSTATE_DATA;
245
-  }else{
246
-    if(r = get_hoststate(t, m)){
247
-      *r = data->head.nstate;
248
-    }else{
249
-      lprintf(0, "%s: hoststate error\n", __func__);
232
+  if(data->head.nstate == MAKUO_RECVSTATE_OPEN){
233
+    mrecv_ack_send_mark(data, m, t);
234
+    if(data->head.flags & MAKUO_FLAG_FMARK){
235
+      return;
250 236
     }
251 237
   }
238
+  if(r = get_hoststate(t, m)){
239
+    *r = data->head.nstate;
240
+  }else{
241
+    lprintf(0, "%s: hoststate error\n", __func__);
242
+  }
252 243
   mrecv_ack_report(m, t, data);
253 244
 }
254 245
 
... ...
@@ -462,49 +467,53 @@ static void mrecv_req_send_open(mfile *m, mdata *r)
462 462
   memcpy(&(a->addr), &(m->addr), sizeof(a->addr));
463 463
 }
464 464
 
465
-static void mrecv_req_send_data(mfile *m,  mdata *r)
465
+static void mrecv_req_send_mark(mfile *m, mdata *r)
466 466
 {
467 467
   if(m->mdata.head.nstate != MAKUO_RECVSTATE_OPEN)
468 468
     return;
469 469
 
470
-  if(m->lickflag){
471
-    if(!seq_delmark(m, r->head.seqno)){
472
-      return;
473
-    }
474
-  }else{
475
-    if(m->mdata.head.seqno > r->head.seqno){
476
-      seq_delmark(m, r->head.seqno);
477
-    }else{
478
-      if(m->mdata.head.seqno < r->head.seqno){
479
-        seq_addmark(m, m->mdata.head.seqno, r->head.seqno);
480
-        m->mdata.head.seqno = r->head.seqno;
481
-      }
482
-      m->mdata.head.seqno++;
483
-    }
470
+  mfile *a = mfins(0);
471
+  if(!a){
472
+    lprintf(0, "%s: out of momory\n", __func__);
473
+    return;
484 474
   }
485
-  if(lseek(m->fd, r->head.seqno * MAKUO_BUFFER_SIZE, SEEK_SET) == -1){
486
-    lprintf(0, "%s: seek error seq=%d size=%d fd=%d err=%d\n", __func__, (int)r->head.seqno, r->head.szdata, m->fd, errno);
487
-    m->mdata.head.ostate = m->mdata.head.nstate;
488
-    m->mdata.head.nstate = MAKUO_RECVSTATE_WRITEERROR;
489
-  }else{
490
-    if(write(m->fd, r->data, r->head.szdata) != -1){
491
-      m->recvcount++;
475
+  a->mdata.head.flags |= MAKUO_FLAG_ACK;
476
+  a->mdata.head.opcode = r->head.opcode;
477
+  a->mdata.head.reqid  = r->head.reqid;
478
+  a->mdata.head.seqno  = r->head.seqno;
479
+  a->mdata.head.ostate = m->mdata.head.nstate;
480
+  a->mdata.head.nstate = MAKUO_RECVSTATE_MARK;
481
+  a->mdata.head.szdata = 0;
482
+
483
+  memcpy(&(a->addr), &(m->addr), sizeof(a->addr));
484
+  if(m->mdata.head.seqno < m->seqnomax){
485
+    seq_addmark(m, m->mdata.head.seqno, m->seqnomax);
486
+    m->mdata.head.seqno = m->seqnomax;
487
+  }
488
+  m->lickflag = 1;
489
+  if(m->markcount){
490
+    if(MAKUO_BUFFER_SIZE < m->markcount * sizeof(uint32_t)){
491
+      a->marksize = MAKUO_BUFFER_SIZE / sizeof(uint32_t);
492 492
     }else{
493
-      lprintf(0, "%s: write error seqno=%d size=%d fd=%d err=%d\n", __func__, (int)r->head.seqno, r->head.szdata, m->fd, errno);
494
-      m->mdata.head.ostate = m->mdata.head.nstate;
495
-      m->mdata.head.nstate = MAKUO_RECVSTATE_WRITEERROR;
493
+      a->marksize = m->markcount;
496 494
     }
495
+    a->markcount = a->marksize;
496
+    a->mark = malloc(a->marksize * sizeof(uint32_t));
497
+    memcpy(a->mark, m->mark, a->marksize * sizeof(uint32_t));
498
+    lprintf(3, "%s: repeat mark=%04d reqest=%03d recv=%06d size=%06d %s\n", __func__,
499
+      m->markcount, a->markcount, m->recvcount, m->seqnomax,  m->fn);
497 500
   }
498
-  if(m->mdata.head.nstate == MAKUO_RECVSTATE_OPEN){
499
-    return;
500
-  }
501
+}
501 502
 
502
-  /*----- write error notlfy -----*/
503
+static void mrecv_req_send_data_write_error(mfile *m, mdata *r)
504
+{
503 505
   mfile *a = mfins(0);
504 506
   if(!a){
505 507
     lprintf(0, "%s: out of momory\n", __func__);
506 508
     return;
507 509
   }
510
+
511
+  /*----- write error notlfy -----*/
508 512
   a->mdata.head.flags |= MAKUO_FLAG_ACK;
509 513
   a->mdata.head.opcode = r->head.opcode;
510 514
   a->mdata.head.reqid  = r->head.reqid;
... ...
@@ -515,12 +524,38 @@ static void mrecv_req_send_data(mfile *m,  mdata *r)
515 515
   memcpy(&(a->addr), &(m->addr), sizeof(a->addr));
516 516
 }
517 517
 
518
-static void mrecv_req_send_mark(mfile *m, mdata *r)
518
+static void mrecv_req_send_data_write(mfile *m, mdata *r)
519 519
 {
520
-  if(m->mdata.head.nstate != MAKUO_RECVSTATE_OPEN)
520
+  if(r->head.szdata == 0){
521 521
     return;
522
+  }
523
+  if(lseek(m->fd, r->head.seqno * MAKUO_BUFFER_SIZE, SEEK_SET) == -1){
524
+    lprintf(0, "%s: seek error seq=%d size=%d fd=%d err=%d\n", __func__, (int)r->head.seqno, r->head.szdata, m->fd, errno);
525
+    m->mdata.head.ostate = m->mdata.head.nstate;
526
+    m->mdata.head.nstate = MAKUO_RECVSTATE_WRITEERROR;
527
+    mrecv_req_send_data_write_error(m, r);
528
+    return; /* seek error */
529
+  }
530
+  if(write(m->fd, r->data, r->head.szdata) != -1){
531
+    m->recvcount++;
532
+  }else{
533
+    lprintf(0, "%s: write error seqno=%d size=%d fd=%d err=%d\n", __func__, (int)r->head.seqno, r->head.szdata, m->fd, errno);
534
+    m->mdata.head.ostate = m->mdata.head.nstate;
535
+    m->mdata.head.nstate = MAKUO_RECVSTATE_WRITEERROR;
536
+    mrecv_req_send_data_write_error(m, r);
537
+  }
538
+}
522 539
 
523
-  mfile *a = mfins(0);
540
+static void mrecv_req_send_data_retry(mfile *m, mdata *r)
541
+{
542
+  mfile *a;
543
+  uint32_t *markptr = m->mark;
544
+  uint32_t  markcnt = m->markcount;
545
+
546
+  lprintf(3, "%s: markcount=%04u recv=%06u size=%06u %s\n",
547
+    __func__, m->markcount, m->recvcount, m->seqnomax,  m->fn);
548
+
549
+  a = mfins(0);
524 550
   if(!a){
525 551
     lprintf(0, "%s: out of momory\n", __func__);
526 552
     return;
... ...
@@ -530,27 +565,68 @@ static void mrecv_req_send_mark(mfile *m, mdata *r)
530 530
   a->mdata.head.reqid  = r->head.reqid;
531 531
   a->mdata.head.seqno  = r->head.seqno;
532 532
   a->mdata.head.ostate = m->mdata.head.nstate;
533
-  a->mdata.head.nstate = MAKUO_RECVSTATE_MARK;
533
+  a->mdata.head.nstate = MAKUO_RECVSTATE_OPEN;
534 534
   a->mdata.head.szdata = 0;
535
-
536 535
   memcpy(&(a->addr), &(m->addr), sizeof(a->addr));
537
-  m->lickflag = 1;
538
-  if(m->mdata.head.seqno < m->seqnomax){
539
-    seq_addmark(m, m->mdata.head.seqno, m->seqnomax);
540
-    m->mdata.head.seqno = m->seqnomax;
541
-  }
542
-  if(m->markcount){
543
-    if(MAKUO_BUFFER_SIZE < m->markcount * sizeof(uint32_t)){
536
+
537
+  while(markcnt){
538
+    a = mfins(0);
539
+    if(!a){
540
+      lprintf(0, "%s: out of momory\n", __func__);
541
+      return;
542
+    }
543
+    a->mdata.head.flags |= MAKUO_FLAG_FMARK;
544
+    a->mdata.head.flags |= MAKUO_FLAG_ACK;
545
+    a->mdata.head.opcode = r->head.opcode;
546
+    a->mdata.head.reqid  = r->head.reqid;
547
+    a->mdata.head.seqno  = r->head.seqno;
548
+    a->mdata.head.ostate = m->mdata.head.nstate;
549
+    a->mdata.head.nstate = MAKUO_RECVSTATE_OPEN;
550
+    a->mdata.head.szdata = 0;
551
+    memcpy(&(a->addr), &(m->addr), sizeof(a->addr));
552
+    if(MAKUO_BUFFER_SIZE < (markcnt * sizeof(uint32_t))){
544 553
       a->marksize = MAKUO_BUFFER_SIZE / sizeof(uint32_t);
545 554
     }else{
546
-      a->marksize = m->markcount;
555
+      a->marksize = markcnt;
547 556
     }
548
-    a->markcount = a->marksize;
549
-    a->mark = malloc(a->marksize * sizeof(uint32_t));
550
-    memcpy(a->mark, m->mark, a->marksize * sizeof(uint32_t));
551
-    lprintf(3, "%s: repeat mark=%04d reqest=%03d recv=%06d size=%06d %s\n", __func__,
552
-      m->markcount, a->markcount, m->recvcount, m->seqnomax,  m->fn);
557
+    if(a->markcount = a->marksize){
558
+      a->mark = malloc(a->marksize * sizeof(uint32_t));
559
+      memcpy(a->mark, markptr, a->marksize * sizeof(uint32_t));
560
+      markptr += a->marksize;
561
+      markcnt -= a->marksize;
562
+    }
563
+  }
564
+}
565
+
566
+static void mrecv_req_send_data(mfile *m, mdata *r)
567
+{
568
+  if(m->mdata.head.nstate != MAKUO_RECVSTATE_OPEN){
569
+    return;
570
+  }
571
+  if(r->head.flags & MAKUO_FLAG_WAIT){
572
+    mrecv_req_send_data_retry(m, r);
573
+    return;
574
+  }
575
+  if(m->lickflag){
576
+    if(seq_delmark(m, r->head.seqno)){
577
+      mrecv_req_send_data_write(m, r);
578
+    }
579
+    return;
580
+  }
581
+  if(m->mdata.head.seqno > r->head.seqno){
582
+    if(seq_delmark(m, r->head.seqno)){
583
+      mrecv_req_send_data_write(m, r);
584
+    }
585
+    return;
586
+  }
587
+  if(m->mdata.head.seqno < r->head.seqno){
588
+    if(seq_addmark(m, m->mdata.head.seqno, r->head.seqno) == 1){
589
+      mrecv_req_send_data_retry(m, r);
590
+    }
591
+    m->mdata.head.seqno = r->head.seqno;
553 592
   }
593
+  mrecv_req_send_data_write(m, r);
594
+  m->mdata.head.seqno++;
554 595
 }
555 596
 
556 597
 static void mrecv_req_send_close(mfile *m, mdata *r)
... ...
@@ -356,49 +356,53 @@ static void msend_req_send_open(int s, mfile *m)
356 356
 
357 357
 static void msend_req_send_markdata(int s, mfile *m)
358 358
 {
359
-  int i;
360 359
   int r;
361 360
   if(!m->markcount){
362 361
     /* close */
363 362
     m->initstate = 1;
364
-    m->mdata.head.seqno  = 0;
365 363
     m->mdata.head.ostate = m->mdata.head.nstate;
366 364
     m->mdata.head.nstate = MAKUO_SENDSTATE_CLOSE;
367 365
     return;
368 366
   }
369
-  lprintf(4, "%s: block send retry %d\n", __func__, m->markcount);
370
-  for(i=0;i<m->markcount;i++){
371
-    m->mdata.head.seqno = m->mark[i];
372
-    lseek(m->fd, m->mdata.head.seqno * MAKUO_BUFFER_SIZE, SEEK_SET);
373
-    r = read(m->fd, m->mdata.data, MAKUO_BUFFER_SIZE);
374
-    if(r>0){
375
-      m->mdata.head.szdata = r;
376
-      msend_packet(s, &(m->mdata), &(m->addr));
367
+  m->markcount--;
368
+  lprintf(4, "%s: block send retry seqno=%u count=%u\n", __func__, m->mark[m->markcount], m->markcount);
369
+  m->mdata.head.seqno = m->mark[m->markcount];
370
+  lseek(m->fd, m->mdata.head.seqno * MAKUO_BUFFER_SIZE, SEEK_SET);
371
+  r = read(m->fd, m->mdata.data, MAKUO_BUFFER_SIZE);
372
+  if(r>0){
373
+    m->mdata.head.szdata = r;
374
+    msend_packet(s, &(m->mdata), &(m->addr));
375
+  }else{
376
+    if(!r){
377
+      lprintf(0, "%s: read eof? seqno=%d\n", __func__, m->mdata.head.seqno);
377 378
     }else{
378
-      if(!r){
379
-        lprintf(0, "%s: read eof? seqno=%d\n", __func__, m->mdata.head.seqno);
380
-      }else{
381
-        lprintf(0, "%s: read err! seqno=%d errno=%d\n", __func__, m->mdata.head.seqno, errno);
382
-      }
379
+      lprintf(0, "%s: read err! seqno=%d errno=%d\n", __func__, m->mdata.head.seqno, errno);
383 380
     }
384 381
   }
385
-  m->markcount = 0;
386
-  m->initstate = 1;
387
-  m->mdata.head.seqno  = 0;
388
-  m->mdata.head.nstate = MAKUO_SENDSTATE_MARK;
389
-  ack_clear(m, MAKUO_RECVSTATE_MARK);
382
+  if(m->markcount == 0){
383
+    m->initstate = 1;
384
+    m->mdata.head.nstate = MAKUO_SENDSTATE_MARK;
385
+  }
390 386
 }
391 387
 
392 388
 static void msend_req_send_filedata(int s, mfile *m)
393 389
 {
394 390
   int readsize;
391
+  if(m->markcount){
392
+    m->markcount--;
393
+    m->mdata.head.seqno = m->mark[m->markcount];
394
+  }else{
395
+    if(m->seqnonow == 0){
396
+      m->waitspan  = 1024;
397
+      m->waitcount = m->waitspan;
398
+    }
399
+    m->mdata.head.seqno = m->seqnonow++;
400
+  }
395 401
   lseek(m->fd, m->mdata.head.seqno * MAKUO_BUFFER_SIZE, SEEK_SET);
396 402
   readsize = read(m->fd, m->mdata.data, MAKUO_BUFFER_SIZE);
397 403
   if(readsize > 0){
398 404
     m->mdata.head.szdata = readsize;
399
-    if(msend_packet(s, &(m->mdata), &(m->addr)) == 1){
400
-      m->mdata.head.seqno++;
401
-    }
405
+    msend_packet(s, &(m->mdata), &(m->addr));
402 406
   }else{
403 407
     if(readsize == -1){
404 408
       /* err */
... ...
@@ -412,6 +416,13 @@ static void msend_req_send_filedata(int s, mfile *m)
412 412
       m->lickflag  = 1;
413 413
     }
414 414
   }
415
+  if(m->waitcount){
416
+    m->waitcount--;
417
+  }else{
418
+    m->sendwait = 1;
419
+    ack_clear(m, MAKUO_RECVSTATE_UPDATE);
420
+    ack_clear(m, MAKUO_RECVSTATE_OPEN);
421
+  }
415 422
 }
416 423
 
417 424
 static void msend_req_send_data(int s, mfile *m)
... ...
@@ -421,6 +432,29 @@ static void msend_req_send_data(int s, mfile *m)
421 421
     m->mdata.head.nstate = MAKUO_SENDSTATE_BREAK;
422 422
     return;
423 423
   }
424
+  if(m->sendwait){
425
+    m->mdata.head.seqno  = 0;
426
+    m->mdata.head.szdata = 0;
427
+    m->mdata.head.flags |= MAKUO_FLAG_WAIT;
428
+    msend_packet(s, &(m->mdata), &(m->addr));
429
+    return;
430
+  }
431
+  if(m->mdata.head.flags & MAKUO_FLAG_WAIT){
432
+    uint32_t wp = m->markcount * 100 / m->waitspan;
433
+    m->mdata.head.flags &= ~MAKUO_FLAG_WAIT;
434
+    /* slow */
435
+    if(m->waitspan > 16){
436
+      if(wp > 50){
437
+        m->waitspan /= 2;
438
+      }
439
+    }
440
+    /* fast */
441
+    if(wp < 10){
442
+      m->waitspan *= 2;
443
+    }
444
+    m->waitcount = m->waitspan;
445
+    lprintf(0,"%s: waitspan=%u markcount=%d\n", __func__, m->waitspan, m->markcount);    
446
+  }
424 447
   if(m->lickflag){
425 448
     msend_req_send_markdata(s, m); /* send retry */
426 449
   }else{
... ...
@@ -434,6 +468,7 @@ static void msend_req_send_mark_init(int s, mfile *m)
434 434
   m->initstate = 0;
435 435
   ack_clear(m, MAKUO_RECVSTATE_UPDATE);
436 436
   ack_clear(m, MAKUO_RECVSTATE_OPEN);
437
+  ack_clear(m, MAKUO_RECVSTATE_MARK);
437 438
   msend_packet(s, &(m->mdata), &(m->addr));
438 439
 }
439 440