00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "midas.h"
00013 #include "msystem.h"
00014 #include "strlcpy.h"
00015 #include <assert.h>
00016 #include <signal.h>
00017
00018 static INT _send_sock;
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081 #define DM_FLUSH 10
00082 #define DM_SEND 11
00083 #define DM_KILL 12
00084 #define DM_TIMEOUT 13
00085 #define DM_ACTIVE_NULL 14
00086
00087 typedef struct {
00088 char *pt;
00089 char *pw;
00090 char *pe;
00091 char *pb;
00092 BOOL full;
00093 DWORD serial;
00094 } DMEM_AREA;
00095
00096 typedef struct {
00097 DMEM_AREA *pa;
00098 DMEM_AREA area1;
00099 DMEM_AREA area2;
00100 DWORD serial;
00101 INT action;
00102 DWORD last_active;
00103 HNDLE sem_send;
00104 HNDLE sem_flush;
00105 } DMEM_BUFFER;
00106
00107 DMEM_BUFFER dm;
00108 INT dm_user_max_event_size;
00109
00110
00111 #endif
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121 INT dm_buffer_create(INT size, INT user_max_event_size)
00122 {
00123
00124 dm.area1.pt = (char *) M_MALLOC(size);
00125 if (dm.area1.pt == NULL)
00126 return (BM_NO_MEMORY);
00127 dm.area2.pt = (char *) M_MALLOC(size);
00128 if (dm.area2.pt == NULL)
00129 return (BM_NO_MEMORY);
00130
00131
00132 if (user_max_event_size > MAX_EVENT_SIZE) {
00133 cm_msg(MERROR, "dm_buffer_create", "user max event size too large");
00134 return BM_MEMSIZE_MISMATCH;
00135 }
00136 dm_user_max_event_size = user_max_event_size;
00137
00138 memset(dm.area1.pt, 0, size);
00139 memset(dm.area2.pt, 0, size);
00140
00141
00142 dm.area1.pb = dm.area1.pt + size - 1024;
00143 dm.area1.pw = dm.area1.pe = dm.area1.pt;
00144 dm.area2.pb = dm.area2.pt + size - 1024;
00145 dm.area2.pw = dm.area2.pe = dm.area2.pt;
00146
00147
00148 #ifdef DM_DEBUG
00149 printf(" in dm_buffer_create ---------------------------------\n");
00150 printf(" %i %p %p %p %p\n", size, dm.area1.pt, dm.area1.pw, dm.area1.pe, dm.area1.pb);
00151 printf(" %i %p %p %p %p\n", size, dm.area2.pt, dm.area2.pw, dm.area2.pe, dm.area2.pb);
00152 #endif
00153
00154
00155 dm.pa = &dm.area1;
00156
00157
00158 dm.area1.full = dm.area2.full = FALSE;
00159
00160
00161 dm.area1.serial = dm.area2.serial = 0;
00162
00163 dm.serial = 1;
00164
00165
00166 dm.last_active = ss_millitime();
00167
00168
00169 _send_sock = rpc_get_event_sock();
00170
00171 #ifdef DM_DUAL_THREAD
00172 {
00173 INT status;
00174 VX_TASK_SPAWN starg;
00175
00176
00177 status = ss_semaphore_create("send", &dm.sem_send);
00178 if (status != SS_CREATED && status != SS_SUCCESS) {
00179 cm_msg(MERROR, "dm_buffer_create", "error in ss_semaphore_create send");
00180 return status;
00181 }
00182 status = ss_semaphore_create("flush", &dm.sem_flush);
00183 if (status != SS_CREATED && status != SS_SUCCESS) {
00184 cm_msg(MERROR, "dm_buffer_create", "error in ss_semaphore_create flush");
00185 return status;
00186 }
00187
00188 memset(&starg, 0, sizeof(VX_TASK_SPAWN));
00189
00190 #ifdef OS_VXWORKS
00191
00192 strcpy(starg.name, "areaSend");
00193 starg.priority = 120;
00194 starg.stackSize = 20000;
00195 #endif
00196
00197 if ((status = ss_thread_create(dm_task, (void *) &starg))
00198 != SS_SUCCESS) {
00199 cm_msg(MERROR, "dm_buffer_create", "error in ss_thread_create");
00200 return status;
00201 }
00202 #ifdef OS_WINNT
00203
00204 ss_semaphore_wait_for(dm.sem_send, 0);
00205 #endif
00206 }
00207 #endif
00208
00209 return CM_SUCCESS;
00210 }
00211
00212
00213 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00214
00215
00216 INT dm_buffer_release(void)
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228 {
00229 if (dm.area1.pt) {
00230 free(dm.area1.pt);
00231 dm.area1.pt = NULL;
00232 }
00233 if (dm.area2.pt) {
00234 free(dm.area2.pt);
00235 dm.area2.pt = NULL;
00236 }
00237 dm.serial = 0;
00238 dm.area1.full = dm.area2.full = TRUE;
00239 dm.area1.serial = dm.area2.serial = 0;
00240
00241 #ifdef DM_DUAL_THREAD
00242
00243 dm.action = DM_KILL;
00244 ss_semaphore_release(dm.sem_send);
00245 ss_semaphore_release(dm.sem_flush);
00246
00247
00248 ss_semaphore_delete(dm.sem_send, 0);
00249 ss_semaphore_delete(dm.sem_flush, 0);
00250 #endif
00251
00252 return CM_SUCCESS;
00253 }
00254
00255
00256 INLINE DMEM_AREA *dm_area_switch(void)
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269 {
00270 volatile BOOL full1, full2;
00271
00272 full1 = dm.area1.full;
00273 full2 = dm.area2.full;
00274
00275 if (!full1 && !full2) {
00276 if (dm.area1.serial <= dm.area2.serial)
00277 return (&(dm.area1));
00278 else
00279 return (&(dm.area2));
00280 }
00281
00282 if (!full1) {
00283 return (&(dm.area1));
00284 } else if (!full2) {
00285 return (&(dm.area2));
00286 }
00287 return (NULL);
00288 }
00289
00290
00291 INLINE BOOL dm_area_full(void)
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303 {
00304 if (dm.pa == NULL || (dm.area1.full && dm.area2.full))
00305 return TRUE;
00306 return FALSE;
00307 }
00308
00309
00310 INLINE BOOL dm_active_full(void)
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323 {
00324
00325 if (dm.pa == NULL)
00326 return TRUE;
00327
00328
00329 if (dm.pa->full)
00330 return TRUE;
00331 return (((POINTER_T) dm.pa->pb - (POINTER_T) dm.pa->pw) < (INT)
00332 (dm_user_max_event_size + sizeof(EVENT_HEADER) + sizeof(INT)));
00333 }
00334
00335
00336 DWORD dm_buffer_time_get(void)
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350 {
00351 return (dm.last_active);
00352 }
00353
00354
00355
00356 EVENT_HEADER *dm_pointer_get(void)
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372 {
00373 int timeout, status;
00374
00375
00376 if (!dm_active_full())
00377 return (EVENT_HEADER *) (dm.pa->pw + sizeof(INT));
00378
00379
00380
00381
00382 dm.pa->serial = dm.serial++;
00383
00384
00385 dm.last_active = ss_millitime();
00386
00387
00388 dm.pa->full = TRUE;
00389
00390
00391 if ((status = dm_area_send()) == RPC_NET_ERROR) {
00392 cm_msg(MERROR, "dm_pointer_get()", "Net error or timeout %i", status);
00393 return NULL;
00394 }
00395
00396
00397 timeout = ss_millitime();
00398 while ((ss_millitime() - timeout) < 10000) {
00399 dm.pa = dm_area_switch();
00400 if (dm.pa != NULL)
00401 return (EVENT_HEADER *) (dm.pa->pw + sizeof(INT));
00402 ss_sleep(200);
00403 #ifdef DM_DEBUG
00404 printf(" waiting for space ... %i dm_buffer %i %i %i %i %i \n",
00405 ss_millitime() - timeout, dm.area1.full, dm.area2.full, dm.area1.serial, dm.area2.serial,
00406 dm.serial);
00407 #endif
00408 }
00409
00410
00411 cm_msg(MERROR, "dm_pointer_get", "Timeout due to buffer full");
00412 return NULL;
00413 }
00414
00415
00416
00417 int dm_pointer_increment(INT buffer_handle, INT event_size)
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433 {
00434 INT aligned_event_size;
00435
00436
00437 if (_send_sock == 0) {
00438 *((INT *) dm.pa->pw) = buffer_handle;
00439 return bm_send_event(buffer_handle, dm.pa->pw + sizeof(INT), event_size, SYNC);
00440 }
00441 aligned_event_size = ALIGN8(event_size);
00442
00443 *((INT *) dm.pa->pw) = buffer_handle;
00444
00445
00446 dm.pa->pw += sizeof(INT) + aligned_event_size;
00447
00448
00449 dm.pa->pe = dm.pa->pw;
00450
00451 return CM_SUCCESS;
00452 }
00453
00454
00455 INLINE INT dm_buffer_send(DMEM_AREA * larea)
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472 {
00473 INT tot_size, nwrite;
00474 char *lpt;
00475
00476
00477 if (_send_sock == 0)
00478 return bm_flush_cache(*((INT *) dm.pa->pw), ASYNC);
00479
00480
00481 lpt = larea->pt;
00482
00483
00484 tot_size = (POINTER_T) larea->pe - (POINTER_T) lpt;
00485
00486
00487 if (tot_size == 0)
00488 return CM_SUCCESS;
00489
00490 #ifdef DM_DEBUG
00491 printf("lpt:%p size:%i ", lpt, tot_size);
00492 #endif
00493 nwrite = send_tcp(_send_sock, lpt, tot_size, 0);
00494 #ifdef DM_DEBUG
00495 printf("nwrite:%i errno:%i\n", nwrite, errno);
00496 #endif
00497 if (nwrite < 0)
00498 return RPC_NET_ERROR;
00499
00500
00501 larea->pw = larea->pe = larea->pt;
00502 larea->full = FALSE;
00503 return CM_SUCCESS;
00504 }
00505
00506
00507 INT dm_area_send(void)
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527 {
00528 #ifdef DM_DUAL_THREAD
00529 INT status;
00530
00531
00532 dm.action = DM_SEND;
00533 ss_semaphore_release(dm.sem_send);
00534 #ifdef OS_WINNT
00535
00536 status = ss_semaphore_wait_for(dm.sem_send, 1);
00537 if (status == SS_NO_SEMAPHORE) {
00538 printf(" timeout while waiting for sem_send\n");
00539 return RPC_NET_ERROR;
00540 }
00541 #endif
00542
00543 return CM_SUCCESS;
00544 #else
00545
00546 INT status = 0;
00547
00548
00549
00550 if (dm.area1.full && dm.area2.full)
00551 if (dm.area1.serial <= dm.area2.serial)
00552 status = dm_buffer_send(&dm.area1);
00553 else
00554 status = dm_buffer_send(&dm.area2);
00555 else if (dm.area1.full)
00556 status = dm_buffer_send(&dm.area1);
00557 else if (dm.area2.full)
00558 status = dm_buffer_send(&dm.area2);
00559 if (status != CM_SUCCESS)
00560 return status;
00561
00562 if (dm.pa == NULL) {
00563 printf(" sync send dm.pa:%p full 1%d 2%d\n", dm.pa, dm.area1.full, dm.area2.full);
00564 dm.pa = &dm.area1;
00565 }
00566 return CM_SUCCESS;
00567 #endif
00568 }
00569
00570
00571 INT dm_task(void *pointer)
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585 {
00586 #ifdef DM_DUAL_THREAD
00587 INT status, timeout;
00588
00589 printf("Semaphores initialization ... in areaSend ");
00590
00591 timeout = ss_millitime();
00592 while ((ss_millitime() - timeout < 3000) && (dm.sem_send == 0))
00593 ss_sleep(200);
00594 if (dm.sem_send == 0)
00595 goto kill;
00596
00597 #ifdef OS_WINNT
00598
00599 ss_semaphore_wait_for(dm.sem_flush, 0);
00600 #endif
00601
00602
00603 printf("task areaSend ready...\n");
00604 while (1) {
00605 if (!dm_area_full()) {
00606
00607 ss_semaphore_wait_for(dm.sem_send, 0);
00608 #ifdef OS_WINNT
00609
00610 ss_semaphore_release(dm.sem_send);
00611 #endif
00612 }
00613 if (dm.action == DM_SEND) {
00614 #ifdef DM_DEBUG
00615 printf("Send %i %i ", dm.area1.full, dm.area2.full);
00616 #endif
00617
00618 if (dm.area1.full && dm.area2.full) {
00619 if (dm.area1.serial <= dm.area2.serial)
00620 status = dm_buffer_send(&dm.area1);
00621 else
00622 status = dm_buffer_send(&dm.area2);
00623 } else if (dm.area1.full)
00624 status = dm_buffer_send(&dm.area1);
00625 else if (dm.area2.full)
00626 status = dm_buffer_send(&dm.area2);
00627
00628 if (status != CM_SUCCESS) {
00629 cm_msg(MERROR, "dm_task", "network error %i", status);
00630 goto kill;
00631 }
00632 }
00633 else if (dm.action == DM_FLUSH) {
00634
00635
00636 if (dm.area1.serial <= dm.area2.serial) {
00637 status = dm_buffer_send(&dm.area1);
00638 if (status != CM_SUCCESS)
00639 goto error;
00640 status = dm_buffer_send(&dm.area2);
00641 if (status != CM_SUCCESS)
00642 goto error;
00643 } else {
00644 status = dm_buffer_send(&dm.area2);
00645 if (status != CM_SUCCESS)
00646 goto error;
00647 status = dm_buffer_send(&dm.area1);
00648 if (status != CM_SUCCESS)
00649 goto error;
00650 }
00651
00652 dm.area1.serial = 0;
00653 dm.area2.serial = dm.serial = 1;
00654 #ifdef DM_DEBUG
00655 printf("dm.action: Flushing ...\n");
00656 #endif
00657
00658 dm.pa = &dm.area1;
00659
00660
00661 ss_semaphore_release(dm.sem_flush);
00662 #ifdef OS_WINNT
00663
00664 ss_semaphore_wait_for(dm.sem_flush, 0);
00665 #endif
00666 }
00667
00668 if (dm.action == DM_KILL)
00669 goto kill;
00670
00671 }
00672
00673
00674 error:
00675 cm_msg(MERROR, "dm_area_flush", "aSync Net error");
00676 kill:
00677 ss_semaphore_release(dm.sem_flush);
00678 #ifdef OS_WINNT
00679 ss_semaphore_wait_for(dm.sem_flush, 1);
00680 #endif
00681 cm_msg(MERROR, "areaSend", "task areaSend exiting now");
00682 exit;
00683 return 1;
00684 #else
00685 printf("DM_DUAL_THREAD not defined %p\n", pointer);
00686 return 0;
00687 #endif
00688 }
00689
00690
00691 INT dm_area_flush(void)
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708 {
00709 INT status;
00710 #ifdef DM_DUAL_THREAD
00711
00712 dm.action = DM_FLUSH;
00713 ss_semaphore_release(dm.sem_send);
00714 #ifdef OS_WINNT
00715
00716 ss_semaphore_wait_for(dm.sem_send, 0);
00717 #endif
00718
00719
00720
00721 status = ss_semaphore_wait_for(dm.sem_flush, 10000);
00722 #ifdef DM_DEBUG
00723 printf("dm_area_flush after waiting %i\n", status);
00724 #endif
00725 #ifdef OS_WINNT
00726 ss_semaphore_release(dm.sem_flush);
00727 #endif
00728
00729 return status;
00730 #else
00731
00732
00733 if (dm.area1.serial <= dm.area2.serial) {
00734 status = dm_buffer_send(&dm.area1);
00735 if (status != CM_SUCCESS)
00736 return status;
00737 status = dm_buffer_send(&dm.area2);
00738 if (status != CM_SUCCESS)
00739 return status;
00740 } else {
00741 status = dm_buffer_send(&dm.area2);
00742 if (status != CM_SUCCESS)
00743 return status;
00744 status = dm_buffer_send(&dm.area1);
00745 if (status != CM_SUCCESS)
00746 return status;
00747 }
00748
00749 dm.area1.serial = dm.area2.serial = 0;
00750 dm.last_active = ss_millitime();
00751 return CM_SUCCESS;
00752 #endif
00753 }
00754
00755
00756 #endif
00757
00758
00759
00760
00761
00762
00763 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00764
00765
00766 #if !defined(OS_VXWORKS)
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776 static char *_event_ring_buffer = NULL;
00777 static INT _eb_size;
00778 static char *_eb_read_pointer, *_eb_write_pointer, *_eb_end_pointer;
00779
00780
00781 INT eb_create_buffer(INT size)
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800 {
00801 _event_ring_buffer = (char *) M_MALLOC(size);
00802 if (_event_ring_buffer == NULL)
00803 return BM_NO_MEMORY;
00804
00805 memset(_event_ring_buffer, 0, size);
00806 _eb_size = size;
00807
00808 _eb_write_pointer = _eb_read_pointer = _eb_end_pointer = _event_ring_buffer;
00809
00810 _send_sock = rpc_get_event_sock();
00811
00812 return CM_SUCCESS;
00813 }
00814
00815
00816 INT eb_free_buffer()
00817
00818
00819
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833 {
00834 if (_event_ring_buffer)
00835 M_FREE(_event_ring_buffer);
00836
00837 _eb_size = 0;
00838 return CM_SUCCESS;
00839 }
00840
00841
00842
00843 INT eb_free_space(void)
00844
00845
00846
00847
00848
00849
00850
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860 {
00861 INT free_space;
00862
00863 if (_event_ring_buffer == NULL) {
00864 cm_msg(MERROR, "eb_get_pointer", "please call eb_create_buffer first");
00865 return -1;
00866 }
00867
00868 if (_eb_write_pointer >= _eb_read_pointer) {
00869 free_space = _eb_size - ((POINTER_T) _eb_write_pointer - (POINTER_T) _event_ring_buffer);
00870 } else if (_eb_write_pointer >= _event_ring_buffer) {
00871 free_space = (POINTER_T) _eb_read_pointer - (POINTER_T) _eb_write_pointer;
00872 } else if (_eb_end_pointer == _event_ring_buffer) {
00873 _eb_write_pointer = _event_ring_buffer;
00874 free_space = _eb_size;
00875 } else if (_eb_read_pointer == _event_ring_buffer) {
00876 free_space = 0;
00877 } else {
00878 _eb_write_pointer = _event_ring_buffer;
00879 free_space = (POINTER_T) _eb_read_pointer - (POINTER_T) _eb_write_pointer;
00880 }
00881
00882 return free_space;
00883 }
00884
00885
00886
00887 DWORD eb_get_level()
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904 {
00905 INT size;
00906
00907 size = _eb_size - eb_free_space();
00908
00909 return (100 * size) / _eb_size;
00910 }
00911
00912
00913
00914 BOOL eb_buffer_full(void)
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931
00932 {
00933 DWORD free_space;
00934
00935 free_space = eb_free_space();
00936
00937
00938 return (free_space < MAX_EVENT_SIZE + sizeof(EVENT_HEADER) + sizeof(INT));
00939 }
00940
00941
00942
00943 EVENT_HEADER *eb_get_pointer()
00944
00945
00946
00947
00948
00949
00950
00951
00952
00953
00954
00955
00956
00957
00958
00959
00960 {
00961
00962 if (eb_buffer_full()) {
00963 #ifdef OS_VXWORKS
00964 logMsg("eb_get_pointer(): Event won't fit: read=%d, write=%d, end=%d\n",
00965 _eb_read_pointer - _event_ring_buffer,
00966 _eb_write_pointer - _event_ring_buffer, _eb_end_pointer - _event_ring_buffer, 0, 0, 0);
00967 #endif
00968 return NULL;
00969 }
00970
00971
00972 return (EVENT_HEADER *) (_eb_write_pointer + sizeof(INT));
00973 }
00974
00975
00976
00977 INT eb_increment_pointer(INT buffer_handle, INT event_size)
00978
00979
00980
00981
00982
00983
00984
00985
00986
00987
00988
00989
00990
00991
00992
00993
00994
00995
00996
00997 {
00998 INT aligned_event_size;
00999
01000
01001 if (_send_sock == 0)
01002 return bm_send_event(buffer_handle, _eb_write_pointer + sizeof(INT), event_size, SYNC);
01003
01004 aligned_event_size = ALIGN8(event_size);
01005
01006
01007 *((INT *) _eb_write_pointer) = buffer_handle;
01008 _eb_write_pointer += sizeof(INT) + aligned_event_size;
01009
01010 if (_eb_write_pointer > _eb_end_pointer)
01011 _eb_end_pointer = _eb_write_pointer;
01012
01013 if (_eb_write_pointer > _event_ring_buffer + _eb_size)
01014 cm_msg(MERROR, "eb_increment_pointer",
01015 "event size (%d) exceeds maximum event size (%d)", event_size, MAX_EVENT_SIZE);
01016
01017 if (_eb_size - ((POINTER_T) _eb_write_pointer - (POINTER_T) _event_ring_buffer) <
01018 (int) (MAX_EVENT_SIZE + sizeof(EVENT_HEADER) + sizeof(INT))) {
01019 _eb_write_pointer = _event_ring_buffer;
01020
01021
01022 if (_eb_read_pointer == _event_ring_buffer)
01023 _eb_write_pointer--;
01024 }
01025
01026 return CM_SUCCESS;
01027 }
01028
01029
01030
01031 INT eb_send_events(BOOL send_all)
01032
01033
01034
01035
01036
01037
01038
01039
01040
01041
01042
01043
01044
01045
01046
01047
01048
01049 {
01050 char *eb_wp, *eb_ep;
01051 INT size, i;
01052 INT opt_tcp_size = rpc_get_opt_tcp_size();
01053
01054
01055 eb_ep = _eb_end_pointer;
01056 eb_wp = _eb_write_pointer;
01057
01058 if (eb_wp == _eb_read_pointer)
01059 return CM_SUCCESS;
01060 if (eb_wp > _eb_read_pointer) {
01061 size = (POINTER_T) eb_wp - (POINTER_T) _eb_read_pointer;
01062
01063
01064 if (size < opt_tcp_size && !send_all)
01065 return CM_SUCCESS;
01066 } else {
01067
01068 size = (POINTER_T) eb_ep - (POINTER_T) _eb_read_pointer;
01069 }
01070
01071 while (size > opt_tcp_size) {
01072
01073 i = send_tcp(_send_sock, _eb_read_pointer, opt_tcp_size, 0);
01074 if (i < 0) {
01075 printf("send_tcp() returned %d\n", i);
01076 cm_msg(MERROR, "eb_send_events", "send_tcp() failed");
01077 return RPC_NET_ERROR;
01078 }
01079
01080 _eb_read_pointer += opt_tcp_size;
01081 if (_eb_read_pointer == eb_ep && eb_wp < eb_ep)
01082 _eb_read_pointer = _eb_end_pointer = _event_ring_buffer;
01083
01084 size -= opt_tcp_size;
01085 }
01086
01087 if (send_all || eb_wp < _eb_read_pointer) {
01088
01089 i = send_tcp(_send_sock, _eb_read_pointer, size, 0);
01090 if (i < 0) {
01091 printf("send_tcp() returned %d\n", i);
01092 cm_msg(MERROR, "eb_send_events", "send_tcp() failed");
01093 return RPC_NET_ERROR;
01094 }
01095
01096 _eb_read_pointer += size;
01097 if (_eb_read_pointer == eb_ep && eb_wp < eb_ep)
01098 _eb_read_pointer = _eb_end_pointer = _event_ring_buffer;
01099 }
01100
01101
01102 if (eb_wp < _event_ring_buffer && _eb_end_pointer == _event_ring_buffer) {
01103 return CM_SUCCESS;
01104 }
01105
01106 if (eb_wp != _eb_read_pointer)
01107 return BM_MORE_EVENTS;
01108
01109 return CM_SUCCESS;
01110 }
01111
01112 #endif
01113
01114
01115 #endif
01116
01117
01118