1 /*
2 * Copyright 1999-2006 University of Chicago
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17
18 #include "globus_i_xio_buffer.h"
19 #include "version.h"
20 #include "globus_xio_http.h"
21
22 #define GROW_SIZE 10
23
24 static int
25 globus_l_xio_buffer_activate();
26
27 static int
28 globus_l_xio_buffer_deactivate();
29
30 GlobusXIODefineModule(buffer) =
31 {
32 "globus_xio_buffer_driver_module",
33 globus_l_xio_buffer_activate,
34 globus_l_xio_buffer_deactivate,
35 GLOBUS_NULL,
36 GLOBUS_NULL,
37 &local_version
38 };
39
40 0 GlobusDebugDefine(GLOBUS_XIO_BUFFER);
41
42 static
43 void
44 globus_l_buffer_write_marker_destroy(
45 void * element)
46 47088 {
47 globus_l_buffer_write_marker_t * write_marker;
48
49 47088 write_marker = (globus_l_buffer_write_marker_t *) element;
50
51 47088 free(write_marker->name);
52 47088 free(write_marker);
53 47088 }
54
55 static
56 void
57 globus_l_buffer_read_marker_destroy(
58 void * element)
59 59485 {
60 globus_l_buffer_read_marker_t * read_marker;
61
62 59485 read_marker = (globus_l_buffer_read_marker_t *) element;
63
64 59485 free(read_marker->name);
65 59485 free(read_marker);
66 59485 }
67
68 static
69 void
70 globus_l_buffer_handle_destroy(
71 globus_l_buffer_handle_t * handle)
72 16674 {
73 GlobusXIOName(globus_l_buffer_handle_destroy);
74 16674 GlobusXIOBufferDebugInternalEnter();
75
76 16674 if(handle->write_buffers)
77 {
78 int i;
79 6018 for(i = 0; i < handle->buffer_count; ++i)
80 {
81 6006 free(handle->write_buffers[i].iov_base);
82 }
83
84 12 free(handle->write_buffers);
85 }
86
87 16674 if(handle->read_buffers)
88 {
89 11467 int i = 0;
90 1229690 for(i = 0; i < handle->buffer_count; ++i)
91 {
92 1218223 globus_assert(handle->read_buffers[i].read_element);
93 1218223 handle->read_buffers[i].read_element->ref_count--;
94 1218223 if(handle->read_buffers[i].read_element->ref_count == 0)
95 {
96 1218223 free(handle->read_buffers[i].read_element->buffer);
97 1218223 free(handle->read_buffers[i].read_element);
98 }
99 }
100
101 11467 free(handle->read_buffers);
102 }
103
104 16674 if(handle->buffer_map)
105 {
106 16674 if(handle->io_mode == GLOBUS_L_XIO_BUFFER_WRITING_MODE)
107 {
108 94 globus_hashtable_destroy_all(
109 &handle->buffer_map, globus_l_buffer_write_marker_destroy);
110 }
111 else
112 {
113 16580 globus_hashtable_destroy_all(
114 &handle->buffer_map, globus_l_buffer_read_marker_destroy);
115 16580 handle->current_read_marker = NULL;
116 }
117 }
118
119 16674 free(handle);
120 16674 }
121
122 static
123 void
124 globus_l_xio_buffer_handle_clear(
125 globus_l_buffer_handle_t * handle)
126 74517 {
127 74517 int jj = 0;
128
129 74517 if(handle->write_buffers)
130 {
131 86104 for(jj = 0; jj < handle->buffer_count; ++jj)
132 {
133 64548 if(handle->write_buffers[jj].iov_len)
134 {
135 64435 free(handle->write_buffers[jj].iov_base);
136 }
137 }
138
139 21556 free(handle->write_buffers);
140 21556 handle->write_buffers = NULL;
141 21556 handle->buffer_count = 0;
142 21556 handle->buffers_length = 0;
143 }
144
145 74517 if(handle->read_buffers)
146 {
147 10025 int i = 0;
148 781375 for(i = 0; i < handle->buffer_count; ++i)
149 {
150 771350 handle->read_buffers[i].read_element->ref_count--;
151 771350 if(handle->read_buffers[i].read_element->ref_count == 0)
152 {
153 771350 free(handle->read_buffers[i].read_element->buffer);
154 771350 free(handle->read_buffers[i].read_element);
155 }
156 }
157
158 10025 free(handle->read_buffers);
159 10025 handle->read_buffers = NULL;
160 10025 handle->buffer_count = 0;
161 10025 handle->buffers_length = 0;
162 }
163
164 74517 if(handle->io_mode == GLOBUS_L_XIO_BUFFER_WRITING_MODE)
165 {
166 52959 globus_hashtable_destroy_all(
167 &handle->buffer_map, globus_l_buffer_write_marker_destroy);
168 }
169 else
170 {
171 21558 globus_hashtable_destroy_all(
172 &handle->buffer_map, globus_l_buffer_read_marker_destroy);
173 21558 handle->current_read_marker = NULL;
174 }
175
176 74517 globus_hashtable_init(&handle->buffer_map, 10,
177 globus_hashtable_string_hash,
178 globus_hashtable_string_keyeq);
179 74517 }
180
181 static
182 void
183 globus_l_xio_buffer_close_callback(
184 struct globus_i_xio_op_s * op,
185 globus_result_t result,
186 globus_size_t nbytes,
187 void * user_args)
188 4 {
189 globus_l_buffer_handle_t * handle;
190 GlobusXIOName(globus_l_xio_buffer_close_callback);
191 4 GlobusXIOBufferDebugInternalEnter();
192
193 4 handle = (globus_l_buffer_handle_t *) user_args;
194
195 4 if(result != GLOBUS_SUCCESS)
196 {
197 0 goto error;
198 }
199
200 4 globus_l_buffer_handle_destroy(handle);
201
202 4 globus_xio_driver_pass_close(op, NULL, NULL);
203
204 4 GlobusXIOBufferDebugInternalExit();
205
206 4 error:
207
208 4 GlobusXIOBufferDebugInternalExitWithError();
209 4 }
210
211 static
212 int
213 globus_l_xio_buffer_get_marked_length(
214 globus_l_buffer_handle_t * handle,
215 globus_l_buffer_read_marker_t * begin_marker,
216 globus_l_buffer_read_marker_t * end_marker)
217 10280 {
218 10280 int len = 0;
219 int buff_ind;
220
221 10280 globus_assert_string(handle, "NULL handle passed to function");
222
223 10280 buff_ind = (begin_marker ? begin_marker->buffer_index : 0);
224
225 10280 if(end_marker)
226 {
227 10270 if(begin_marker->buffer_index == end_marker->buffer_index)
228 {
229 6029 len += end_marker->offset - begin_marker->offset;
230 }
231 else
232 {
233 4241 len += handle->read_buffers[buff_ind].length -
234 begin_marker->offset;
235
236 4241 buff_ind++;
237 498976 while(buff_ind < end_marker->buffer_index)
238 {
239 490494 len += handle->read_buffers[buff_ind].length;
240 490494 buff_ind++;
241 }
242
243 4241 len += end_marker->offset;
244 }
245 }
246 else
247 {
248 10 len += handle->read_buffers[buff_ind].length -
249 (begin_marker ? begin_marker->offset : 0);
250 10 buff_ind++;
251 136 while(buff_ind < handle->buffer_count)
252 {
253 116 len += handle->read_buffers[buff_ind].length;
254 116 buff_ind++;
255 }
256 }
257
258 10280 return len;
259 }
260
261 static
262 globus_result_t
263 globus_l_xio_buffer_get_marked_buffers(
264 globus_l_buffer_handle_t * handle,
265 globus_l_buffer_read_marker_t * begin_marker,
266 globus_l_buffer_read_marker_t * end_marker,
267 char ** out_buffer,
268 size_t * out_size)
269 10280 {
270 10280 int len = 0;
271 int buff_ind;
272 10280 int bytes_copied = 0;
273 int begin_offset;
274 int last_buffer;
275
276 10280 globus_result_t result = GLOBUS_SUCCESS;
277 GlobusXIOName(globus_l_xio_buffer_get_marked_buffers);
278 10280 GlobusXIOBufferDebugEnter();
279
280 10280 globus_assert_string(handle, "NULL handle passed to function");
281 10280 buff_ind = (begin_marker ? begin_marker->buffer_index : 0);
282
283 10280 len = globus_l_xio_buffer_get_marked_length(
284 handle, begin_marker, end_marker);
285 10280 *out_buffer = globus_malloc(len);
286
287 10280 if(!*out_buffer)
288 {
289 0 *out_size = 0;
290 0 result = GlobusXIOBufferErrorOutOfMemory;
291 0 goto exit;
292 }
293
294 10280 GlobusXIOBufferDebugPrintf(GLOBUS_XIO_BUFFER_DEBUG_BUFFERS,
295 ("MARKED BUFFER LENGTH: %d\n", len));
296
297 /* For the first time through the copy loop, we may start copying
298 * from the middle of a buffer, if that's where the marker is.
299 * All subsequent iterations, this will be 0
300 */
301 10280 begin_offset =
302 (begin_marker ? begin_marker->offset : 0);
303
304 /* If we have an end marker, we will stop copying after we copy the
305 * portion of the buffer which contains it. Otherwise we will copy
306 * all buffers
307 */
308 10280 last_buffer =
309 (end_marker ? end_marker->buffer_index + 1 : handle->buffer_count);
310
311 515411 for (; buff_ind < last_buffer; buff_ind++)
312 {
313 size_t to_copy;
314
315 /* Don't copy more than the amount of data we want from the current
316 * buffer
317 */
318 505131 if (len > handle->read_buffers[buff_ind].length -
319 begin_offset)
320 {
321 494851 to_copy = handle->read_buffers[buff_ind].length -
322 begin_offset;
323 }
324 else
325 {
326 /* Or more than the size of the total amount we want to copy. */
327 10280 to_copy = len;
328 }
329 505131 memcpy(*out_buffer + bytes_copied,
330 handle->read_buffers[buff_ind].read_element->buffer +
331 handle->read_buffers[buff_ind].start_pos +
332 begin_offset,
333 to_copy);
334
335 505131 bytes_copied += to_copy;
336 505131 len -= to_copy;
337
338 505131 begin_offset = 0;
339 }
340
341 10280 GlobusXIOBufferDebugPrintf(GLOBUS_XIO_BUFFER_DEBUG_BUFFERS,
342 ("MARKED BUFFER BYTES COPIED: %d\n",
343 bytes_copied));
344
345 10280 *out_size = bytes_copied;
346
347 10280 exit:
348 10280 GlobusXIOBufferDebugExit();
349 10280 return result;
350 }
351
352 /*
353 * write interface function
354 */
355 static
356 globus_result_t
357 globus_l_xio_buffer_write(
358 void * driver_specific_handle,
359 const globus_xio_iovec_t * iovec,
360 int iovec_count,
361 globus_xio_operation_t op)
362 347363 {
363 int wait_for;
364 int jj;
365 347363 int append_length = 0;
366 347363 int grow_length = 0;
367 347363 globus_l_buffer_handle_t * handle = NULL;
368 globus_xio_iovec_t * append_iovec;
369 347363 globus_result_t result = GLOBUS_SUCCESS;
370 globus_l_buffer_attr_t * attr;
371 GlobusXIOName(globus_l_xio_buffer_write);
372 347363 GlobusXIOBufferDebugEnter();
373
374 347363 if(!driver_specific_handle)
375 {
376 0 result = GlobusXIOErrorParameter("driver_specific_handle");
377 0 goto error;
378 }
379
380 347363 handle = (globus_l_buffer_handle_t *) driver_specific_handle;
381
382 347363 wait_for = globus_xio_operation_get_wait_for(op);
383
384 347363 if(iovec_count < 1)
385 {
386 0 if(wait_for > 0)
387 {
388 0 result = GlobusXIOErrorParameter("iovec_count");
389 }
390 0 goto error;
391 }
392
393 347363 if(handle->io_mode != GLOBUS_L_XIO_BUFFER_WRITING_MODE)
394 {
395 2 globus_l_xio_buffer_handle_clear(handle);
396 2 handle->io_mode = GLOBUS_L_XIO_BUFFER_WRITING_MODE;
397 }
398
399 347363 if(handle->mode == GLOBUS_L_XIO_BUFFERING_DISABLED)
400 {
401 6 result = globus_xio_driver_pass_write(
402 op, (globus_xio_iovec_t *)iovec, iovec_count, wait_for,
403 NULL, NULL);
404 6 GlobusXIOBufferDebugExit();
405 6 return result;
406 }
407
408 347357 if(!handle->write_buffers)
409 {
410 globus_l_buffer_write_marker_t * marker;
411
412 21562 handle->write_buffers = globus_malloc(sizeof(globus_xio_iovec_t));
413 21562 if(!handle->write_buffers)
414 {
415 0 result = GlobusXIOBufferErrorOutOfMemory;
416 0 GlobusXIOBufferDebugExit();
417 0 return result;
418 }
419 21562 handle->write_buffers[0].iov_base = NULL;
420 21562 handle->write_buffers[0].iov_len = 0;
421
422 21562 marker = globus_malloc(sizeof(globus_l_buffer_write_marker_t));
423 21562 if(!marker)
424 {
425 0 result = GlobusXIOBufferErrorOutOfMemory;
426 0 GlobusXIOBufferDebugExit();
427 0 return result;
428 }
429 21562 marker->name = strdup("DEFAULT");
430 21562 marker->index = 0;
431 21562 globus_hashtable_insert(&handle->buffer_map, marker->name, marker);
432 21562 handle->buffer_count++;
433 21562 handle->current_write_buffer = 0;
434 }
435
436 347357 append_iovec = &handle->write_buffers[handle->current_write_buffer];
437
438 694714 for(jj = 0; jj < iovec_count; ++jj)
439 {
440 347357 append_length += iovec[jj].iov_len;
441 }
442
443 347357 if(append_iovec->iov_len + append_length > 0)
444 {
445 347235 append_iovec->iov_base = realloc(
446 append_iovec->iov_base, append_iovec->iov_len + append_length);
447 347235 if(!append_iovec->iov_base)
448 {
449 0 result = GlobusXIOBufferErrorOutOfMemory;
450 0 GlobusXIOBufferDebugExit();
451 0 return result;
452 }
453
454 347235 grow_length = append_iovec->iov_len;
455 694470 for(jj = 0; jj < iovec_count; ++jj)
456 {
457 347235 memcpy((char *)(append_iovec->iov_base) + grow_length,
458 iovec[jj].iov_base, iovec[jj].iov_len);
459 347235 grow_length += iovec[jj].iov_len;
460 }
461
462 347235 append_iovec->iov_len += append_length;
463 347235 handle->buffers_length += append_length;
464 }
465
466 347357 attr = globus_xio_operation_get_data_descriptor(
467 op,
468 GLOBUS_FALSE);
469
470 368829 if (attr != NULL && attr->flush)
471 {
472 21472 result = globus_xio_driver_pass_write(
473 op,
474 handle->write_buffers,
475 handle->buffer_count,
476 handle->buffers_length,
477 NULL,
478 NULL);
479
480 21472 if (result != GLOBUS_SUCCESS)
481 {
482 0 goto error;
483 }
484 21472 handle->mode = GLOBUS_L_XIO_BUFFERING_DISABLED;
485 }
486 else
487 {
488 325885 globus_xio_driver_finished_write(
489 op, GLOBUS_SUCCESS, append_length);
490 }
491
492 347357 GlobusXIOBufferDebugExit();
493 347357 return result;
494
495 0 error:
496
497 0 GlobusXIOBufferDebugExitWithError();
498 0 return result;
499 }
500
501 static
502 globus_result_t
503 globus_l_xio_buffer_cntl(
504 void * driver_specific_handle,
505 int cmd,
506 va_list ap)
507 266897 {
508 globus_l_buffer_handle_t * handle;
509 266897 globus_result_t result = GLOBUS_SUCCESS;
510 globus_l_buffer_write_marker_t * write_marker;
511 266897 globus_l_buffer_write_marker_t * begin_write_marker = NULL;
512 266897 globus_l_buffer_write_marker_t * end_write_marker = NULL;
513 266897 globus_l_buffer_read_marker_t * begin_read_marker = NULL;
514 266897 globus_l_buffer_read_marker_t * end_read_marker = NULL;
515 266897 globus_l_buffer_read_marker_t * read_marker = NULL;
516
517 char * tag_name;
518 char ** out_buffer;
519 size_t * out_length;
520 char * begin_tag_name;
521 char * end_tag_name;
522 int jj;
523 int * buffer_length;
524 int index, bufind, buflen;
525
526 GlobusXIOName(globus_l_xio_buffer_cntl);
527 266897 GlobusXIOBufferDebugEnter();
528
529 266897 if(!driver_specific_handle)
530 {
531 0 GlobusXIOBufferDebugExitWithError();
532 0 return GlobusXIOErrorParameter("driver_specific_handle");
533 }
534
535 266897 handle = (globus_l_buffer_handle_t *) driver_specific_handle;
536
537 266897 switch(cmd)
538 {
539 case GLOBUS_XIO_BUFFER_GET_LENGTH:
540 21556 buffer_length = va_arg(ap, int *);
541 21556 *buffer_length = handle->buffers_length;
542 21556 break;
543
544 case GLOBUS_XIO_BUFFER_CLEAR:
545
546 53043 handle->mode = GLOBUS_L_XIO_BUFFERING_DISABLED;
547 53043 globus_l_xio_buffer_handle_clear(handle);
548 53043 break;
549
550 case GLOBUS_XIO_BUFFER_ENABLE_READ_BUFFERING:
551
552 26429 handle->io_mode = GLOBUS_L_XIO_BUFFER_READING_MODE;
553 26429 handle->mode = GLOBUS_L_XIO_BUFFERING_ENABLED;
554 26429 break;
555
556 case GLOBUS_XIO_BUFFER_ENABLE_WRITE_BUFFERING:
557
558 21568 handle->io_mode = GLOBUS_L_XIO_BUFFER_WRITING_MODE;
559 21568 handle->mode = GLOBUS_L_XIO_BUFFERING_ENABLED;
560 21568 break;
561
562 case GLOBUS_XIO_BUFFER_SET_MARKER:
563
564 35528 if(handle->io_mode == GLOBUS_L_XIO_BUFFER_WRITING_MODE)
565 {
566 27528 if(handle->buffer_count == 0)
567 {
568 6 handle->current_write_buffer = -1;
569 }
570
571 27528 handle->write_buffers = realloc(
572 handle->write_buffers,
573 sizeof(globus_xio_iovec_t) * (handle->buffer_count + 1));
574 27528 if((handle->current_write_buffer + 1) < handle->buffer_count)
575 {
576 58 memmove(handle->write_buffers +
577 handle->current_write_buffer + 2,
578 handle->write_buffers +
579 handle->current_write_buffer + 1,
580 sizeof(globus_xio_iovec_t) *
581 (handle->buffer_count -
582 (handle->current_write_buffer + 1)));
583
584 58 write_marker = globus_hashtable_first(
585 &handle->buffer_map);
586 881 while(write_marker)
587 {
588 765 if(write_marker->index > handle->current_write_buffer)
589 {
590 414 write_marker->index++;
591 }
592
593 765 write_marker = globus_hashtable_next(
594 &handle->buffer_map);
595 }
596 }
597
598 27528 handle->current_write_buffer++;
599 27528 handle->write_buffers[handle->current_write_buffer].iov_base
600 = NULL;
601 27528 handle->write_buffers[handle->current_write_buffer].iov_len
602 = 0;
603
604 27528 handle->buffer_count++;
605
606 27528 write_marker = globus_malloc(
607 sizeof(globus_l_buffer_write_marker_t));
608 27528 if(!write_marker)
609 {
610 0 result = GlobusXIOBufferErrorOutOfMemory;
611 0 GlobusXIOBufferDebugExit();
612 0 return result;
613 }
614 27528 write_marker->name = strdup(va_arg(ap, char *));
615 27528 write_marker->index = handle->current_write_buffer;
616 27528 globus_hashtable_insert(&handle->buffer_map,
617 write_marker->name,
618 write_marker);
619 }
620 else
621 {
622 8000 tag_name = va_arg(ap, char *);
623
624 8000 if(globus_hashtable_lookup(&handle->buffer_map, tag_name))
625 {
626 0 break;
627 }
628
629 8000 read_marker = globus_malloc(sizeof(globus_l_buffer_read_marker_t));
630 8000 if(!read_marker)
631 {
632 0 result = GlobusXIOBufferErrorOutOfMemory;
633 0 GlobusXIOBufferDebugExit();
634 0 return result;
635 }
636
637 8000 read_marker->name = strdup(tag_name);
638 8000 read_marker->offset = handle->traverse_position;
639 8000 read_marker->buffer_index = handle->traverse_buffer_index;
640 8000 read_marker->next = NULL;
641 8000 globus_hashtable_insert(
642 &handle->buffer_map, read_marker->name, read_marker);
643 8000 if(handle->current_read_marker)
644 {
645 7992 handle->current_read_marker->next = read_marker;
646 }
647
648 8000 handle->current_read_marker = read_marker;
649 }
650
651 35528 break;
652
653 case GLOBUS_XIO_BUFFER_SET_READ_MARKER_AT_INDEX:
654
655 49517 tag_name = va_arg(ap, char *);
656 49517 if(globus_hashtable_lookup(&handle->buffer_map, tag_name))
657 {
658 34 break;
659 }
660
661 49483 read_marker = globus_malloc(sizeof(globus_l_buffer_read_marker_t));
662 49483 if(!read_marker)
663 {
664 0 result = GlobusXIOBufferErrorOutOfMemory;
665 0 goto failed_set_marker;
666 }
667 49483 read_marker->name = strdup(tag_name);
668 49483 index = va_arg(ap, int);
669
670 49483 if(index > handle->buffers_length)
671 {
672 0 result = GlobusXIOErrorBufferSetMarkerFailed(read_marker->name);
673 0 goto failed_set_marker;
674 }
675
676 49483 buflen = 0;
677 2012203 for(bufind = 0; bufind < handle->buffer_count; ++bufind)
678 {
679 2012203 if(index < (buflen + handle->read_buffers[bufind].length))
680 {
681 49483 read_marker->offset = index - buflen;
682 49483 read_marker->buffer_index = bufind;
683 49483 globus_hashtable_insert(
684 &handle->buffer_map, read_marker->name, read_marker);
685 49483 if(handle->current_read_marker)
686 {
687 28009 read_marker->next = handle->current_read_marker->next;
688 28009 handle->current_read_marker->next = read_marker;
689 }
690 else
691 {
692 21474 read_marker->next = NULL;
693 }
694
695 49483 handle->current_read_marker = read_marker;
696 49483 break;
697 }
698 else
699 {
700 1962720 buflen += handle->read_buffers[bufind].length;
701 }
702 }
703
704 49483 break;
705
706 case GLOBUS_XIO_BUFFER_GET_MARKED_BUFFER:
707
708 4000 tag_name = va_arg(ap, char *);
709 4000 out_buffer = va_arg(ap, char **);
710 4000 out_length = va_arg(ap, size_t *);
711
712 4000 *out_buffer = NULL;
713 4000 *out_length = 0;
714
715 4000 if(handle->io_mode == GLOBUS_L_XIO_BUFFER_WRITING_MODE)
716 {
717
718 0 write_marker = globus_hashtable_lookup(
719 &handle->buffer_map, tag_name);
720 0 if(!write_marker)
721 {
722 0 result = GlobusXIOErrorBufferMarkerNotFound(tag_name);
723 0 goto tag_not_found;
724 }
725
726 0 if(handle->write_buffers[write_marker->index].iov_len)
727 {
728 0 *out_buffer = globus_malloc(
729 handle->write_buffers[write_marker->index].iov_len);
730 0 memcpy(*out_buffer,
731 handle->write_buffers[write_marker->index].iov_base,
732 handle->write_buffers[write_marker->index].iov_len);
733
734 0 *out_length =
735 handle->write_buffers[write_marker->index].iov_len;
736 }
737 }
738 else
739 {
740 4000 if(!handle->read_buffers)
741 {
742 0 result = GlobusXIOErrorBufferEmpty();
743 0 goto buffer_empty;
744 }
745
746 4000 read_marker = globus_hashtable_lookup(
747 &handle->buffer_map, tag_name);
748 4000 if(!read_marker)
749 {
750 0 result = GlobusXIOErrorBufferMarkerNotFound(tag_name);
751 0 goto tag_not_found;
752 }
753
754
755 4000 result = globus_l_xio_buffer_get_marked_buffers(
756 handle, read_marker, read_marker->next,
757 out_buffer, out_length);
758 4000 if(result != GLOBUS_SUCCESS)
759 {
760 0 goto error;
761 }
762 }
763
764 4000 break;
765
766 case GLOBUS_XIO_BUFFER_GET_MARKED_BUFFERS:
767
768 6309 begin_tag_name = va_arg(ap, char *);
769 6309 end_tag_name = va_arg(ap, char *);
770 6309 out_buffer = va_arg(ap, char **);
771 6309 out_length = va_arg(ap, size_t *);
772
773 6309 *out_buffer = NULL;
774 6309 *out_length = 0;
775
776 6309 if(handle->io_mode == GLOBUS_L_XIO_BUFFER_WRITING_MODE)
777 {
778 29 int begin_index = 0;
779 29 int end_index = handle->buffer_count;
780
781 29 if(begin_tag_name)
782 {
783 29 begin_write_marker = globus_hashtable_lookup(
784 &handle->buffer_map, begin_tag_name);
785 29 if(begin_write_marker)
786 {
787 29 begin_index = begin_write_marker->index;
788 }
789 }
790
791 29 if(end_tag_name)
792 {
793 29 end_write_marker = globus_hashtable_lookup(
794 &handle->buffer_map, end_tag_name);
795 29 if(end_write_marker)
796 {
797 29 end_index = end_write_marker->index;
798 }
799 }
800
801 29 for(jj = begin_index;
802 58 jj < end_index; ++jj)
803 {
804 29 *out_buffer = realloc(
805 *out_buffer,
806 handle->write_buffers[jj].iov_len + *out_length);
807 29 memcpy(*out_buffer + *out_length,
808 handle->write_buffers[jj].iov_base,
809 handle->write_buffers[jj].iov_len);
810 29 *out_length += handle->write_buffers[jj].iov_len;
811 }
812 }
813 else
814 {
815 6280 if(!handle->read_buffers)
816 {
817 0 result = GlobusXIOErrorBufferEmpty();
818 0 goto buffer_empty;
819 }
820
821 6280 if(begin_tag_name)
822 {
823 6274 begin_read_marker = globus_hashtable_lookup(
824 &handle->buffer_map, begin_tag_name);
825 }
826
827 6280 if(end_tag_name)
828 {
829 6274 end_read_marker = globus_hashtable_lookup(
830 &handle->buffer_map, end_tag_name);
831 }
832
833 6280 result = globus_l_xio_buffer_get_marked_buffers(
834 handle, begin_read_marker, end_read_marker,
835 out_buffer, out_length);
836 6280 if(result != GLOBUS_SUCCESS)
837 {
838 0 goto error;
839 }
840 }
841
842 6309 break;
843
844 case GLOBUS_XIO_BUFFER_RESET_READ_POSITION:
845
846 21472 handle->mode = GLOBUS_L_XIO_BUFFERING_DONE;
847 21472 handle->traverse_position = 0;
848 21472 handle->traverse_buffer_index = 0;
849 21472 break;
850
851 case GLOBUS_XIO_BUFFER_SET_READ_POSITION_TO_MARKER:
852
853 2000 tag_name = va_arg(ap, char *);
854
855 2000 read_marker = globus_hashtable_lookup(&handle->buffer_map, tag_name);
856 2000 if(!read_marker)
857 {
858 0 result = GlobusXIOErrorBufferMarkerNotFound(tag_name);
859 0 goto tag_not_found;
860 }
861
862 2000 handle->mode = GLOBUS_L_XIO_BUFFERING_DONE;
863 2000 handle->traverse_position = read_marker->offset;
864 2000 handle->traverse_buffer_index = read_marker->buffer_index;
865 2000 break;
866
867 case GLOBUS_XIO_BUFFER_SET_WRITE_POSITION_TO_MARKER:
868
869 25475 tag_name = va_arg(ap, char *);
870
871 25475 write_marker = globus_hashtable_lookup(&handle->buffer_map, tag_name);
872 25475 if(!write_marker)
873 {
874 2 result = GlobusXIOErrorBufferMarkerNotFound(tag_name);
875 2 goto tag_not_found;
876 }
877
878 25473 if(handle->write_buffers[write_marker->index].iov_base != NULL)
879 {
880 21464 handle->write_buffers = realloc(
881 handle->write_buffers,
882 (handle->buffer_count + 1) * sizeof(globus_xio_iovec_t));
883 21464 memmove(handle->write_buffers + write_marker->index + 1,
884 handle->write_buffers + write_marker->index,
885 sizeof(globus_xio_iovec_t) *
886 (handle->buffer_count - write_marker->index));
887 21464 handle->write_buffers[write_marker->index].iov_base = NULL;
888 21464 handle->write_buffers[write_marker->index].iov_len = 0;
889 21464 handle->buffer_count++;
890
891 21464 handle->current_write_buffer = write_marker->index;
892
893 21464 write_marker = globus_hashtable_first(&handle->buffer_map);
894 85862 while(write_marker)
895 {
896 42934 if(write_marker->index > handle->current_write_buffer)
897 {
898 6 write_marker->index++;
899 }
900
901 42934 write_marker = globus_hashtable_next(&handle->buffer_map);
902 }
903 }
904 else
905 {
906 4009 handle->current_write_buffer = write_marker->index;
907 }
908
909 25473 break;
910
911 default:
912
913 0 result = GlobusXIOErrorInvalidCommand(cmd);
914 0 GlobusXIOBufferDebugExitWithError();
915 0 return result;
916 }
917
918 266895 GlobusXIOBufferDebugExit();
919 266895 return result;
920
921 2 tag_not_found:
922
923 2 buffer_empty:
924
925 2 failed_set_marker:
926
927 2 error:
928
929 2 GlobusXIOBufferDebugExitWithError();
930 2 return result;
931 }
932
933 static
934 void
935 globus_l_xio_buffer_read_callback(
936 globus_xio_operation_t op,
937 globus_result_t result,
938 globus_size_t nbytes,
939 void * user_arg)
940 2011043 {
941 globus_l_buffer_handle_t * handle;
942 2011043 int i = 0;
943 2011043 int read_len = 0;
944 2011043 int cpylen = 0;
945 2011043 int added_buffer = 0;
946 GlobusXIOName(globus_l_xio_buffer_read_callback);
947 2011043 GlobusXIOBufferDebugInternalEnter();
948
949 2011043 handle = (globus_l_buffer_handle_t *) user_arg;
950
951 2011043 if(handle->mode == GLOBUS_L_XIO_BUFFERING_ENABLED)
952 {
953 2011043 if(globus_xio_error_is_eof(result))
954 {
955 11447 result = GlobusXIOErrorBufferEOF();
956 }
957
958 2011043 if(!handle->read_buffers)
959 {
960 21492 handle->read_buffers = globus_malloc(
961 sizeof(globus_l_read_buffer_t) * GROW_SIZE);
962 21492 if(!handle->read_buffers)
963 {
964 0 result = GlobusXIOBufferErrorOutOfMemory;
965 0 globus_xio_driver_finished_read(op, result, nbytes);
966 0 goto error;
967 }
968
969 21492 memset(handle->read_buffers, 0,
970 GROW_SIZE * sizeof(globus_l_read_buffer_t));
971 21492 handle->read_buffers_available = GROW_SIZE;
972 }
973 1989551 else if(handle->read_buffers_available == 0)
974 {
975 188097 handle->read_buffers = realloc(
976 handle->read_buffers,
977 sizeof(globus_l_read_buffer_t) *
978 (handle->buffer_count + GROW_SIZE));
979 188097 if(!handle->read_buffers)
980 {
981 0 result = GlobusXIOBufferErrorOutOfMemory;
982 0 globus_xio_driver_finished_read(op, result, nbytes);
983 0 goto error;
984 }
985 188097 memset(handle->read_buffers +
986 handle->buffer_count,
987 0, GROW_SIZE * sizeof(globus_l_read_buffer_t));
988 188097 handle->read_buffers_available += GROW_SIZE;
989 }
990
991 2011043 if(nbytes > 0)
992 {
993 1989573 handle->read_buffers[handle->buffer_count].read_element =
994 malloc(sizeof(globus_l_read_buffer_element_t));
995 1989573 if(!handle->read_buffers[handle->buffer_count].read_element)
996 {
997 0 result = GlobusXIOBufferErrorOutOfMemory;
998 0 globus_xio_driver_finished_read(op, result, nbytes);
999 0 goto error;
1000 }
1001 1989573 memset(handle->read_buffers[handle->buffer_count].read_element,
1002 0, sizeof(globus_l_read_buffer_element_t));
1003
1004 1989573 handle->read_buffers[handle->buffer_count].read_element->buffer =
1005 malloc(nbytes);
1006 1989573 if(!handle->read_buffers[handle->buffer_count].read_element->buffer)
1007 {
1008 0 result = GlobusXIOBufferErrorOutOfMemory;
1009 0 globus_xio_driver_finished_read(op, result, nbytes);
1010 0 goto error;
1011 }
1012 1989573 handle->read_buffers[handle->buffer_count].
1013 read_element->ref_count++;
1014 }
1015
1016 2011043 cpylen = nbytes;
1017 4000616 for(i = 0; read_len < nbytes && i < handle->user_iovec_count; ++i)
1018 {
1019 1989573 cpylen = nbytes - read_len;
1020 1989573 cpylen = (cpylen < handle->user_iovec[i].iov_len) ? cpylen :
1021 handle->user_iovec[i].iov_len;
1022 1989573 added_buffer = 1;
1023
1024 1989573 if(handle->user_iovec[i].iov_len > 0)
1025 {
1026 1989573 memcpy(
1027 handle->read_buffers[handle->buffer_count].
1028 read_element->buffer +
1029 handle->read_buffers[handle->buffer_count].length,
1030 handle->user_iovec[i].iov_base,
1031 cpylen);
1032 1989573 handle->traverse_position =
1033 handle->read_buffers[handle->buffer_count].length +
1034 cpylen;
1035 1989573 handle->traverse_buffer_index = handle->buffer_count;
1036
1037 1989573 handle->read_buffers[handle->buffer_count].length += cpylen;
1038 1989573 read_len += cpylen;
1039 }
1040 }
1041
1042 2011043 if(added_buffer)
1043 {
1044 1989573 handle->buffer_count++;
1045 1989573 handle->buffers_length += nbytes;
1046 1989573 handle->read_buffers_available--;
1047 }
1048
1049 2011043 globus_xio_driver_finished_read(op, result, nbytes);
1050 }
1051 else
1052 {
1053 0 goto error;
1054 }
1055
1056 2011043 error:
1057
1058 2011043 GlobusXIOBufferDebugInternalExit();
1059 2011043 }
1060
1061 static
1062 globus_result_t
1063 globus_l_xio_buffer_read(
1064 void * driver_specific_handle,
1065 const globus_xio_iovec_t * iovec,
1066 int iovec_count,
1067 globus_xio_operation_t op)
1068 2310278 {
1069 globus_l_buffer_handle_t * handle;
1070 2310278 globus_result_t result = GLOBUS_SUCCESS;
1071 size_t wait_for;
1072 2310278 int i = 0;
1073 2310278 int copy_length = 0;
1074 2310278 int total_copy = 0;
1075
1076 GlobusXIOName(globus_l_xio_buffer_read);
1077 2310278 GlobusXIOBufferDebugEnter();
1078
1079 2310278 if(!driver_specific_handle)
1080 {
1081 0 result = GlobusXIOErrorParameter("driver_specific_handle");
1082 0 goto error;
1083 }
1084
1085 2310278 handle = (globus_l_buffer_handle_t *) driver_specific_handle;
1086
1087 2310278 wait_for = globus_xio_operation_get_wait_for(op);
1088
1089 2310278 if(handle->io_mode != GLOBUS_L_XIO_BUFFER_READING_MODE)
1090 {
1091 21472 globus_l_xio_buffer_handle_clear(handle);
1092 21472 handle->io_mode = GLOBUS_L_XIO_BUFFER_READING_MODE;
1093 }
1094
1095 2310278 if(handle->mode == GLOBUS_L_XIO_BUFFERING_ENABLED)
1096 {
1097 2011043 handle->user_iovec = (globus_xio_iovec_t *) iovec;
1098 2011043 handle->user_iovec_count = iovec_count;
1099
1100 2011043 result = globus_xio_driver_pass_read(
1101 op, (globus_xio_iovec_t *) iovec, iovec_count, wait_for,
1102 globus_l_xio_buffer_read_callback, handle);
1103 2011043 if(result != GLOBUS_SUCCESS)
1104 {
1105 0 goto error;
1106 }
1107 }
1108 299235 else if(handle->mode == GLOBUS_L_XIO_BUFFERING_DISABLED)
1109 {
1110 26562 result = globus_xio_driver_pass_read(
1111 op, (globus_xio_iovec_t *) iovec, iovec_count, wait_for,
1112 NULL, NULL);
1113 26562 if(result != GLOBUS_SUCCESS)
1114 {
1115 0 goto error;
1116 }
1117 }
1118 272673 else if(handle->mode == GLOBUS_L_XIO_BUFFERING_DONE)
1119 {
1120 272673 if(!handle->read_buffers)
1121 {
1122 0 goto error;
1123 }
1124
1125 545346 for(i = 0; i < iovec_count; ++i)
1126 {
1127 272673 if(iovec[i].iov_len > 0)
1128 {
1129 int buff_ind;
1130 int cbuff_unread_length;
1131 272673 int current_iovec_offset = 0;
1132
1133 /* For each non-empty iovec, we'll copy data up to the
1134 * iovec limit from the buffers.
1135 */
1136 272673 for (buff_ind = handle->traverse_buffer_index;
1137 2502490 buff_ind < handle->buffer_count;
1138 1957144 buff_ind++)
1139 {
1140 2229817 cbuff_unread_length =
1141 handle->read_buffers[buff_ind].length -
1142 handle->traverse_position;
1143
1144 /* Copy at smaller of remaining space in the iovec
1145 * and cbuff_unread_length
1146 */
1147 2229817 if(iovec[i].iov_len - current_iovec_offset
1148 > cbuff_unread_length)
1149 {
1150 1978612 copy_length = cbuff_unread_length;
1151 }
1152 else
1153 {
1154 251205 copy_length = iovec[i].iov_len - current_iovec_offset;
1155 }
1156
1157 2229817 memcpy((char *) iovec[i].iov_base + current_iovec_offset,
1158 handle->read_buffers[buff_ind].read_element->buffer +
1159 handle->read_buffers[buff_ind].start_pos +
1160 handle->traverse_position,
1161 copy_length);
1162
1163 /* Track how much is copied, offset into our destination,
1164 * and traverse position
1165 */
1166 2229817 total_copy += copy_length;
1167 2229817 current_iovec_offset += copy_length;
1168 2229817 handle->traverse_position += copy_length;
1169
1170 /* If we copied to the end of the current buffer, we'll
1171 * advance to the next one (resetting the traverse
1172 * position), unless this is the last buffer.
1173 */
1174 2229817 if (handle->traverse_position ==
1175 handle->read_buffers[buff_ind].length)
1176 {
1177 1985551 if (handle->traverse_buffer_index + 1 <
1178 handle->buffer_count)
1179 {
1180 1964079 handle->traverse_position = 0;
1181 1964079 handle->traverse_buffer_index++;
1182 }
1183 else
1184 {
1185 /* Nothing more in our buffers. Trigger EOF
1186 * Condition
1187 */
1188 21472 result = GlobusXIOErrorBufferEOF();
1189 21472 break;
1190 }
1191 }
1192
1193 2208345 if (current_iovec_offset == iovec[i].iov_len)
1194 {
1195 /* Can't put any more data into the iovec, so we break
1196 */
1197 251201 break;
1198 }
1199 }
1200 }
1201 }
1202
1203 272673 if (total_copy == 0)
1204 {
1205 0 result = GlobusXIOErrorBufferEOF();
1206 }
1207
1208 272673 globus_xio_driver_finished_read(op, result, total_copy);
1209 272673 result = GLOBUS_SUCCESS;
1210 }
1211
1212 2310278 error:
1213
1214 2310278 if(result != GLOBUS_SUCCESS)
1215 {
1216 0 GlobusXIOBufferDebugExitWithError();
1217 0 return result;
1218 }
1219
1220 2310278 GlobusXIOBufferDebugExit();
1221 2310278 return result;
1222 }
1223
1224 static
1225 void
1226 globus_l_xio_buffer_open_callback(
1227 globus_xio_operation_t op,
1228 globus_result_t result,
1229 void * user_arg)
1230 16685 {
1231 globus_l_buffer_handle_t * handle;
1232
1233 GlobusXIOName(globus_l_xio_buffer_open_callback);
1234 16685 GlobusXIOBufferDebugEnter();
1235
1236 16685 handle = (globus_l_buffer_handle_t *) user_arg;
1237
1238 16685 if(result != GLOBUS_SUCCESS)
1239 {
1240 28 globus_l_buffer_handle_destroy(handle);
1241 28 handle = NULL;
1242 }
1243
1244 16685 globus_xio_driver_finished_open(handle, op, result);
1245
1246 16685 GlobusXIOBufferDebugExit();
1247 16685 }
1248
1249
1250
1251 static
1252 globus_result_t
1253 globus_l_xio_buffer_open(
1254 const globus_xio_contact_t * contact_info,
1255 void * driver_link,
1256 void * driver_attr,
1257 globus_xio_operation_t op)
1258 16685 {
1259 globus_result_t result;
1260 globus_l_buffer_handle_t * handle;
1261 int rc;
1262
1263 GlobusXIOName(globus_l_xio_buffer_open);
1264 16685 GlobusXIOBufferDebugEnter();
1265
1266 16685 handle = malloc(sizeof(globus_l_buffer_handle_t));
1267 16685 if(!handle)
1268 {
1269 0 result = GlobusXIOErrorMemory("handle");
1270 0 goto error;
1271 }
1272 16685 memset(handle, 0, sizeof(globus_l_buffer_handle_t));
1273
1274 16685 rc = globus_hashtable_init(&handle->buffer_map, 10,
1275 globus_hashtable_string_hash,
1276 globus_hashtable_string_keyeq);
1277 16685 if (rc != GLOBUS_SUCCESS)
1278 {
1279 0 result = GlobusXIOErrorMemory("handle.buffer_map");
1280 0 goto free_handle_error;
1281 }
1282
1283 16685 result = globus_xio_driver_pass_open(
1284 op, contact_info,
1285 globus_l_xio_buffer_open_callback, handle);
1286 16685 if (result != GLOBUS_SUCCESS)
1287 {
1288 0 goto destroy_handle_error;
1289 }
1290
1291 16685 GlobusXIOBufferDebugExit();
1292 16685 return GLOBUS_SUCCESS;
1293
1294 0 destroy_handle_error:
1295 0 globus_hashtable_destroy(&handle->buffer_map);
1296 0 free_handle_error:
1297 0 free(handle);
1298 0 error:
1299
1300 0 GlobusXIOBufferDebugExitWithError();
1301 0 return result;
1302 }
1303
1304 static
1305 globus_result_t
1306 globus_l_xio_buffer_close(
1307 void * driver_specific_handle,
1308 void * attr,
1309 globus_xio_operation_t op)
1310 16646 {
1311 16646 globus_result_t result = GLOBUS_SUCCESS;
1312 16646 globus_l_buffer_handle_t * handle = NULL;
1313
1314 GlobusXIOName(globus_l_xio_buffer_close);
1315 16646 GlobusXIOBufferDebugEnter();
1316
1317 16646 if(!driver_specific_handle)
1318 {
1319 0 GlobusXIOBufferDebugExitWithError();
1320 0 return GlobusXIOErrorParameter("driver_specific_handle");
1321 }
1322
1323 16646 handle = (globus_l_buffer_handle_t *) driver_specific_handle;
1324
1325 16646 if(handle->io_mode == GLOBUS_L_XIO_BUFFER_WRITING_MODE &&
1326 handle->mode == GLOBUS_L_XIO_BUFFERING_ENABLED)
1327 {
1328 4 handle->io_mode = GLOBUS_L_XIO_BUFFERING_DONE;
1329 4 result = globus_xio_driver_pass_write(
1330 op, handle->write_buffers, handle->buffer_count,
1331 handle->buffers_length, globus_l_xio_buffer_close_callback,
1332 handle);
1333 4 if(result != GLOBUS_SUCCESS)
1334 {
1335 0 goto error;
1336 }
1337
1338 4 goto exit;
1339 }
1340
1341 16642 error:
1342
1343 16642 if(handle)
1344 {
1345 16642 globus_l_buffer_handle_destroy(handle);
1346 }
1347
1348 16642 result = globus_xio_driver_pass_close(
1349 op,
1350 NULL, NULL);
1351
1352 16646 exit:
1353
1354 16646 GlobusXIOBufferDebugExit();
1355 16646 return result;
1356 }
1357
1358 globus_result_t
1359 globus_l_xio_buffer_accept(
1360 void * driver_server,
1361 globus_xio_operation_t accept_op)
1362 5389 {
1363 5389 return globus_xio_driver_pass_accept(accept_op,
1364 NULL, NULL);
1365 }
1366
1367 static
1368 globus_result_t
1369 globus_l_xio_buffer_attr_init(
1370 void ** out_attr)
1371 21474 {
1372 globus_l_buffer_attr_t * attr;
1373 21474 globus_result_t result = GLOBUS_SUCCESS;
1374 GlobusXIOName(globus_l_xio_attr_init);
1375 21474 GlobusXIOBufferDebugEnter();
1376
1377 21474 attr = malloc(sizeof(globus_l_buffer_attr_t));
1378 21474 if (attr == NULL)
1379 {
1380 0 result = GlobusXIOBufferErrorOutOfMemory;
1381
1382 0 goto out;
1383 }
1384 21474 attr->flush = GLOBUS_FALSE;
1385
1386 21474 out:
1387 21474 *out_attr = attr;
1388 21474 GlobusXIOBufferDebugExit();
1389 21474 return result;
1390 }
1391
1392 static
1393 globus_result_t
1394 globus_l_xio_buffer_attr_copy(
1395 void ** dst,
1396 void * src)
1397 0 {
1398 globus_l_buffer_attr_t * attr;
1399 0 globus_result_t result = GLOBUS_SUCCESS;
1400 GlobusXIOName(globus_l_xio_attr_copy);
1401 0 GlobusXIOBufferDebugEnter();
1402
1403 0 attr = malloc(sizeof(globus_l_buffer_attr_t));
1404 0 if (attr == NULL)
1405 {
1406 0 result = GlobusXIOBufferErrorOutOfMemory;
1407
1408 0 goto out;
1409 }
1410 0 attr->flush = ((globus_l_buffer_attr_t *)src)->flush;
1411
1412 0 out:
1413 0 GlobusXIOBufferDebugExit();
1414 0 *dst = attr;
1415
1416 0 return result;
1417 }
1418 /* globus_l_xio_buffer_attr_copy() */
1419
1420
1421 static
1422 globus_result_t
1423 globus_l_xio_buffer_attr_cntl(
1424 void * driver_attr,
1425 int cmd,
1426 va_list ap)
1427 21474 {
1428 21474 globus_l_buffer_attr_t * attr = driver_attr;
1429 21474 globus_result_t result = GLOBUS_SUCCESS;
1430 GlobusXIOName(globus_l_xio_attr_cntl);
1431 21474 GlobusXIOBufferDebugEnter();
1432
1433 21474 switch (cmd)
1434 {
1435 case GLOBUS_XIO_BUFFER_FLUSH:
1436 21474 attr->flush = GLOBUS_TRUE;
1437 21474 break;
1438 default:
1439 0 result = GlobusXIOErrorParameter("cmd");
1440 }
1441
1442 21474 GlobusXIOBufferDebugExit();
1443 21474 return result;
1444 }
1445 /* globus_l_xio_buffer_attr_cntl() */
1446
1447 globus_result_t
1448 globus_l_xio_buffer_attr_destroy(
1449 void * driver_attr)
1450 11541 {
1451 11541 free(driver_attr);
1452
1453 11541 return GLOBUS_SUCCESS;
1454 }
1455 /* globus_l_xio_buffer_attr_destroy() */
1456
1457 /*
1458 * Driver load function
1459 */
1460 static globus_result_t
1461 globus_l_xio_buffer_init(
1462 globus_xio_driver_t * out_driver)
1463 844 {
1464 globus_xio_driver_t driver;
1465 globus_result_t result;
1466 GlobusXIOName(globus_l_xio_buffer_init);
1467 844 GlobusXIOBufferDebugEnter();
1468
1469 844 result = globus_xio_driver_init(&driver, "buffer", NULL);
1470 844 if(result != GLOBUS_SUCCESS)
1471 {
1472 0 GlobusXIOBufferDebugExitWithError();
1473 0 return result;
1474 }
1475
1476 844 globus_xio_driver_set_transform(
1477 driver,
1478 globus_l_xio_buffer_open,
1479 globus_l_xio_buffer_close,
1480 globus_l_xio_buffer_read,
1481 globus_l_xio_buffer_write,
1482 globus_l_xio_buffer_cntl,
1483 NULL);
1484
1485 844 globus_xio_driver_set_attr(
1486 driver,
1487 globus_l_xio_buffer_attr_init,
1488 globus_l_xio_buffer_attr_copy,
1489 globus_l_xio_buffer_attr_cntl,
1490 globus_l_xio_buffer_attr_destroy);
1491
1492 844 globus_xio_driver_set_server(
1493 driver,
1494 NULL,
1495 globus_l_xio_buffer_accept,
1496 NULL,
1497 NULL,
1498 NULL,
1499 NULL);
1500
1501 844 *out_driver = driver;
1502
1503 844 GlobusXIOBufferDebugExit();
1504 844 return GLOBUS_SUCCESS;
1505 }
1506
1507 /*
1508 * Driver unload function
1509 */
1510 static void
1511 globus_l_xio_buffer_destroy(
1512 globus_xio_driver_t driver)
1513 317 {
1514 GlobusXIOName(globus_l_xio_buffer_destroy);
1515 317 GlobusXIOBufferDebugEnter();
1516 317 globus_xio_driver_destroy(driver);
1517 317 GlobusXIOBufferDebugExit();
1518 return;
1519 }
1520
1521
1522 /*
1523 * Driver definition
1524 */
1525 GlobusXIODefineDriver(
1526 buffer,
1527 globus_l_xio_buffer_init,
1528 globus_l_xio_buffer_destroy);
1529
1530 /*
1531 * Module activation
1532 */
1533 static
1534 int
1535 globus_l_xio_buffer_activate(void)
1536 844 {
1537 int rc;
1538
1539 GlobusXIOName(globus_l_xio_buffer_activate);
1540 844 GlobusDebugInit(GLOBUS_XIO_BUFFER, TRACE INTERNAL_TRACE MARKERS BUFFERS);
1541 844 GlobusXIOBufferDebugEnter();
1542 844 rc = globus_module_activate(GLOBUS_COMMON_MODULE);
1543 844 if(rc == GLOBUS_SUCCESS)
1544 {
1545 844 GlobusXIORegisterDriver(buffer);
1546 }
1547 844 GlobusXIOBufferDebugExit();
1548 844 return rc;
1549 }
1550
1551 /*
1552 * Module deactivation
1553 */
1554 static
1555 int
1556 globus_l_xio_buffer_deactivate(void)
1557 317 {
1558 int rc;
1559 GlobusXIOName(globus_l_xio_buffer_deactivate);
1560 317 GlobusXIOBufferDebugEnter();
1561 317 GlobusXIOUnRegisterDriver(buffer);
1562 317 rc = globus_module_deactivate(GLOBUS_COMMON_MODULE);
1563 317 GlobusXIOBufferDebugExit();
1564 317 GlobusDebugDestroy(GLOBUS_XIO_BUFFER);
1565 317 return rc;