-
Notifications
You must be signed in to change notification settings - Fork 7
/
evpath.h
2413 lines (2251 loc) · 95.6 KB
/
evpath.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
#ifndef __EVPATH__H__
#define __EVPATH__H__
/*! \file */
#include "ffs.h"
#include "atl.h"
#ifdef __cplusplus
extern "C" {
#endif
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
struct _CManager;
struct _CMConnection;
struct _CMFormat;
/*!
* CManager is the root of control flow and message handling in a CM program.
*
* CManager is an opaque handle.
*/
typedef struct _CManager *CManager;
/*!
* CMConnection is a handle to a communications link.
*
* CManager is an opaque handle.
*/
typedef struct _CMConnection *CMConnection;
/*!
* CMFormat is a handle to a registered native format.
*
* CMFormat is an opaque handle. It is the return value from
* CMregister_format() and is used both to identify data for writing (in
* CMwrite() and CMwrite_attr() and to register handlers for incoming data
* (with CMregister_handler()).
*/
typedef struct _CMFormat *CMFormat;
/*!
* CMTaskHandle is a handle to a delayed or periodic task.
*/
typedef struct _CMTaskHandle *CMTaskHandle;
/*!
* buf_entry is a structure used to return the lengths of encoded events
* and a pointer to their locations.
*/
typedef struct buf_entry {
size_t length; /*!< length of the encoded buffer */
void *buffer; /*!< base address of the encoded buffer */
} *EVevent_list;
/*!
* The prototype for a CM data handling function.
*
* CM allows application-routines matching this prototype to be registered
* as data handlers.
* \param cm The CManager with which this handler was registered.
* \param conn The CMConnection upon which the message arrived.
* \param message A pointer to the incoming data, cast to void*. The real
* data is formatted to match the fields of with which the format was
* registered.
* \param client_data This value is the same client_data value that was
* supplied in the CMregister_handler() call. It is not interpreted by CM,
* but instead can be used to maintain some application context.
* \param attrs The attributes (set of name/value pairs) that this message
* was delivered with. These are determined by the transport and may
* include those specified in CMwrite_attr() when the data was written.
*/
typedef void (*CMHandlerFunc) (CManager cm,
CMConnection conn,
void *message, void *client_data,
attr_list attrs);
/*!
* The prototype for a CM polling handler (and others).
*
* Functions matching of this prototype can be registered with CMadd_poll(),
* CMadd_periodic_task(), CMadd_delayed_task() and CMadd_shutdown_task().
* \param cm The CManager with which this handler was registered.
* \param client_data This value is the same client_data value that was
* supplied in the CMadd_poll() call. It is not interpreted by CM,
* but instead can be used to maintain some application context.
*/
typedef void (*CMPollFunc) (CManager cm, void *client_data);
/*!
* The prototype for a CM connection close handler.
*
* Functions matching of this prototype can be registered with
* CMregister_close_handler().
* \param cm The CManager with which this handler was registered.
* \param conn The CMConnection which is being closed.
* \param client_data This value is the same client_data value that was
* supplied in the CMregister_close_handler() call. It is not interpreted
* by CM, but instead can be used to maintain some application context.
*/
typedef void (*CMCloseHandlerFunc) (CManager cm, CMConnection conn,
void *client_data);
/*!
* The prototype for a CM write possible callback.
*
* Functions matching of this prototype can be registered with
* CMregister_write_callback().
* \param cm The CManager with which this callback function was registered.
* \param conn The CMConnection upon which a non-blocking write is now (potentially) possible.
* \param client_data This value is the same client_data value that was
* supplied in the CMregister_write_callback() call. It is not interpreted
* by CM, but instead can be used to maintain some application context.
*/
typedef void (*CMWriteCallbackFunc) (CManager cm, CMConnection conn,
void *client_data);
/*!
* create a CManager.
*
* CManager is the root of control flow and message handling in a CM program.
*/
/*NOLOCK*/
extern CManager CManager_create();
/*!
* create a CManager.
*
* CManager is the root of control flow and message handling in a CM program.
* This version of a call selects a specific control_module for managing waiting
* network and control events, currently either "select" or "epoll".
*/
/*NOLOCK*/
extern CManager CManager_create_control(char *control_module);
/*!
* close a CManager
*
* the close operation shuts down all connections and causes the
* termination of any network handling thread.
* \param cm The CManager to be shut down.
*/
extern void CManager_close (CManager cm);
/*!
* specify a numerical identifier to be used as part of a trace output filename
*
* \param ID the numerical identifier;
*
*
*/
/*NOLOCK*/
extern void CMTrace_file_id (int ID);
/*!
* fork a thread to handle the network input operations of a CM.
*
* \param cm The CManager whose input should be handled by a new thread.
* \return
* - 0 if a communications manager thread cannot be forked
* - 1 success
* \warning Only one thread should be handling input for a CM. If this call
* is used then no other thread should call CMpoll_network() or
* CMrun_network().
* \warning If this call is to be used (or indeed if any threading is to be
* used), one of the gen_thread init routines should be called <b>before</b>
* the call to CManager_create(). Otherwise bad things will happen.
*/
extern int CMfork_comm_thread (CManager cm);
/*!
* Tell CM to listen for incoming network connections.
*
* \param cm The CManager which should listen.
* \return the number of transports which successfully initiated connection
* listen operations (by reporting contact attributes).
* \note CMlisten() is identical to calling CMlisten_specific() with a NULL
* value for the listen_info parameter.
* \note The listening transports will add their contact information to the
* list returned by CMget_contact_list().
*/
extern int CMlisten (CManager cm);
/*!
* Tell CM to listen for incoming network connections with
* specific characteristics.
*
* \param cm The CManager which should listen.
* \param listen_info An attribute list to be passed to the
* transport-provided listen operations of all currently-loaded transports.
* \return the number of transports which successfully initiated connection
* listen operations (by reporting contact attributes).
* \note The listen_info value is interpreted by each individual transport.
* An incomplete (and probably dated) list of transports that use this include:
* - the <b>sockets</b> transport which uses the CM_IP_PORT attribute to control
* which port it listens on. If this attribute is not present it listens
* on any available port.
* - the <b>rudp</b> transport which uses the CM_UDP_PORT attribute to control
* which port it listens on. If this attribute is not present it listens
* on any available port.
* - the <b>enet</b> transport which uses the CM_ENET_PORT attribute to control
* which port it listens on. If this attribute is not present it listens
* on any available port.
* - the <b>udp</b> transport - a raw unreliable UDP transport.
* - the <b>multicast</b> transport - a raw unreliable Multicast transport.
* - the <b>nnti</b> transport - a multi-network RDMA transport.
* - the <b>ib</b> transport - kind-of-functional InfiniBand transport.
*/
extern int CMlisten_specific (CManager cm, attr_list listen_info);
/*!
* get the contact information for this CM.
*
* This call returns the set of attributes that define the contact
* information for the network transports that have performed listen
* operations.
* \param cm the CManager for which to return contact information.
* \return the contact list.
*/
extern attr_list
CMget_contact_list (CManager cm);
/*!
* insert contact information into this CM.
*
* This call adds to the set of attributes that define the contact
* information for the network transports that have performed listen
* operations.
* \param cm the CManager for which to add contact information.
* \param attrs the information to add.
*/
extern void
CM_insert_contact_info (CManager cm, attr_list attrs);
/*!
* get a specific subset of the contact information for this CM.
*
* This call returns the set of attributes that define the contact
* information for a particular network transport. If no listen operation
* has been performed on that transport, one will be done with a NULL attr
* list.
* \param cm the CManager for which to return contact information.
* \param attrs the attribute list specifying the transport.
* \return the contact list.
*/
extern attr_list
CMget_specific_contact_list (CManager cm, attr_list attrs);
/*!
* get a thread-owned version of a shared attribute list in a thread-safe way
* \param cm the CManager which owns the attribute list.
* \param attrs the shared attribute list (from CMget_contact list, etc.)
* \return a single-owner contact list
*/
extern attr_list
CMderef_and_copy_list(CManager cm, attr_list attrs);
/*!
* check to see if this is contact information for <b>this</b> CM.
*
* Since attribute lists are generally opaque, it is not necessarily obvious
* when you have a set of contract attributes that is actually your own
* contact list. This call is designed to answer that question.
*
* \param cm The CManager whose contact information should be compared.
* \param attrs The contact list to compare.
* \return 1 if for some loaded transport the attrs list matches the contact
* information in the cm. 0 otherwise.
*/
extern int
CMcontact_self_check (CManager cm, attr_list attrs);
/*!
* acquire a (possibly existing) connection to another CM process.
*
* \param cm The CManager in which to make the connection.
* \param contact_list The attribute list specifying contact information for
* the remote CM.
* \return A CMConnection value, or NULL in the event of failure.
*
* CMget_conn() attempts to determine if the contact attribute match any
* existing connection (Using the transport connection_eq() method). If a
* connection matches, that connection's reference count is incremented and
* its value is returned. If no connection matches, a CMinitiate_conn() is
* performed using the contact list and its result value is returned.
*/
extern CMConnection
CMget_conn (CManager cm, attr_list contact_list);
/*!
* initiate connection to another CM process.
*
* \param cm The CManager in which to make the connection.
* \param contact_list The attribute list specifying contact information for
* the remote CM.
* \return A CMConnection value, or NULL in the event of failure.
*
* CMinitiate_conn() will attempt to initiate a connection using each of the
* currently loaded transports. It will return the first that succeeds, or
* NULL if none succeed.
* \note If the contact list contains a CM_TRANSPORT attribute with a string
* value, CMinitiate_conn() will attempt to load that transport, then if that
* succeeds will attempt to initiate a connection using only that transport.
*/
extern CMConnection
CMinitiate_conn (CManager cm, attr_list contact_list);
/*!
* kill and potentially deallocate a connection.
*
* \param conn the CMConnection to kill
*
* CMConnection_close decrements the reference count of a connection. If
* the resulting reference count is zero, then the connection is shut down.
* All resources associated with the connection are free'd, the close
* handler is called and the CMConnection structure itself is free'd.
* \warning CMConnection values should not be used after
* CMConnection_close(). CMConnection_close() should only be used on
* CMConnection values created with CMget_conn() or CMinitiate_conn(), not
* with connections that are passively created (accepted through CMlisten()).
*/
extern void
CMConnection_close (CMConnection conn);
/*!
* manually increment the reference count of a connection.
*
* \param conn the CMConnection whose count should be incremented.
* \note Used if some mechanism other than CMget_conn() is used to "share"
* connection in multiple contexts so that it is closed only when all users
* have closed it.
*/
extern void
CMConnection_add_reference (CMConnection conn);
/*!
* manually decrement the reference count of a connection.
*
* \param conn the CMConnection whose count should be decremented.
* \note Used if some mechanism other than CMget_conn() is used to "share"
* connection in multiple contexts so that it is closed only when all users
* have closed it.
*/
extern void
CMConnection_dereference (CMConnection conn);
/*!
* register a function to be called when a connection is closed.
*
* \param conn the connection with which the function is associated.
* \param func the function to be called when the connection closes.
* \param client_data An uninterpreted value that is passed to the function
* when it is called.
* \note There can be only one close handler per connection. Multiple
* registrations overwrite each other.
*/
extern void
CMconn_register_close_handler (CMConnection conn,
CMCloseHandlerFunc func,
void *client_data);
/*!
* return the list of attributes associated with a connection.
*
* \param conn the connection for which to return the attributes.
* \return an attr_list value containing connection attributes.
*/
extern attr_list
CMConnection_get_attrs (CMConnection conn);
/*!
* modify the characteristics of a connection.
*
* \param conn the connection for to modify characteristics.
* \param attrs the characteristics to apply (specific to CM and transport).
* \return a true/false failure value.
*/
extern int
CMConnection_set_character (CMConnection conn, attr_list attrs);
/*!
* return connection 'i' associated with a CM value.
*
* \param cm the cmanager from which to return a connection.
* \param i the index value into the CManager's list of connections.
* \return a CMConnection value associated with connection 'i'
*/
extern CMConnection
CMget_indexed_conn (CManager cm, int i);
/*!
* register a format with CM.
*
* \param cm The CManager in which to register the format.
* \param format_list The FM format list which describes the structure.
* It should contain the transitive closure of all data types necessary to
* specify the message representation. The list is terminated with a
* <tt>{NULL, NULL, 0, NULL}</tt> value.
*
* Registering a format is a precursor to sending a message or registering a
* handler for incoming messages.
*/
extern CMFormat
CMregister_format (CManager cm, FMStructDescList format_list);
/*!
* register a simple (no internal structures) format with CM.
*
* \param cm The CManager in which to register the format.
* \param format_name The name of the data/message structure being registered
* \param field_list The FM field list which describes the structure, listing all
* structure fields (their names, data types, offsets and sizes).
* As with all FMFieldLists, the list is terminated with a <tt>{NULL, NULL, 0, 0}</tt> value.
* \param struct_size The (padded if necessary) size of the structure, typically as returned by sizeof().
*
* Registering a format is a precursor to sending a message or registering a
* handler for incoming messages. This call is the equivalent to calling CMregister_format(),
* specifying a single entry in the format_list parameter with the format_name, field_list and
* struct_size and the opt_info specified as NULL.
*/
extern CMFormat
CMregister_simple_format (CManager cm, char *format_name, FMFieldList field_list, int struct_size);
/*!
* lookup the CMFormat associated with a particular FMStructDescList
*
* \param cm The CManager in which the format was registered.
* \param format_list The format list which was used in the registration.
*
* CMLookup_format() addresses a specific problem particular to libraries.
* CMwrite() requires a CMFormat value that results from a
* CMregister_format() call. Efficiency would dictate that the
* CMregister_format() be performed once and the CMFormat value used
* repeatedly for multiple writes. However, libraries which want to avoid
* the use of static variables, or which wish to support multiple CM values
* per process have no convenient way to store the CMFormat values for
* reuse. CMlookup_format() exploits the fact that field_lists are
* often constants with fixed addresses (I.E. their memory is not reused for
* other field lists later in the application). This call quickly looks up
* the CMFormat value in a CM by searching for a matching field_list
* address.
* \warning You should *not* use this convenience routine if you cannot
* guarantee that all field lists used to register formats have a unique
* address.
*/
extern CMFormat CMlookup_format (CManager cm, FMStructDescList format_list);
/*!
* return the FMContext value used by a CM.
*
* \param cm The CManager from which to return the FMcontext;
*
* CMget_FMcontext() returns the FMcontext value in use by the CManager
*/
/*NOLOCK*/
extern FMContext CMget_FMcontext(CManager cm);
/*!
* send a message on a connection.
*
* \param conn The CMConnection upon which to send the message.
* \param format The CMFormat value returned by CMregister_format().
* \param data The unencoded message, cast to a <tt>void*</tt> value.
* \return
* - 1 if the write was successful.
* - 0 if the write did not complete successfully.
* \note CMwrite() is equivalent to CMwrite_attr() with a NULL value
* passed for the attrs parameter.
*/
extern int
CMwrite (CMConnection conn, CMFormat format, void *data);
/*!
* send a message on a connection with particular attributes.
*
* \param conn The CMConnection upon which to send the message.
* \param format The CMFormat value returned by CMregister_format().
* \param data The unencoded message, cast to a <tt>void*</tt> value.
* \param attrs The set of name/value attributes with which to write the data.
* \return
* - 1 if the write was successful.
* - 0 if the write did not complete successfully.
* \note The values in the attrs parameter serve two purposes. First,
* they may be interpreted by CM or the CM transport layers on either
* the writing or reading sides to customize event delivery. Second,
* they are made available (perhaps with additional transport-specific
* attributes) to the read-side handler in the attrs argument to the
* CMHandlerFunc that handles the message.
* \note CMwrite_attr() with a NULL value for the attrs parameter is
* equivalent to CMwrite().
*/
extern int
CMwrite_attr (CMConnection conn, CMFormat format, void *data,
attr_list attrs);
/*!
* register a function to be called when message matching a particular
* format arrives.
*
* \param format The CMFormat value returned by CMregister_format()
* \param handler The function to be called to handle the message.
* \param client_data An uninterpreted value that is passed to the function
* when it is called.
*/
extern void
CMregister_handler (CMFormat format, CMHandlerFunc handler,
void *client_data);
/*!
* register a function to be called when a write is again possible on a particular CMconnection.
*
* \param conn The CMConnection upon which to send the message.
* \param handler The function to be called to handle the message.
* \param client_data An uninterpreted value that is passed to the function
* when it is called.
*
*
*/
extern void
CMregister_write_callback (CMConnection conn,
CMWriteCallbackFunc handler,
void *client_data);
/*!
* test whether a write to a particular connection would block
*
* \param conn The CMConnection to test
* \return boolean TRUE(1) if the write would certainly block and
* FALSE(0) if it may not.
* At the network level, we likely only know that <B>something</B> can be
* sent, not how much. So even if this returns false, a write may still
* block at the network level. If this happens, CM will copy the remaining
* bytes and allow the CMwrite() to return, finishing the send
* asynchronously. However, if a CMwrite() is initiated when
* write_would_block() is already TRUE, the write <b>will block</b> until
* the blocking condition is gone (I.E. CMConnection_write_would_block() is
* again FALSE).)
*/
extern int
CMConnection_write_would_block (CMConnection conn);
/*!
* assume control over a incoming buffer of data.
*
* This call is designed to be used inside a CMHandlerFunc. Normally data
* buffers are recycled and CM only guarantees that the data delivered to a
* CMHandlerFunc will be valid for the duration of the call. In that
* circumstance, a handler that wanted to preserve the data for longer than
* its own duration (to pass it to a thread or enter it into some other data
* structure for example) would have to copy the data. To avoid that
* inefficiency, CMtake_buffer() allows the handler to take control of the
* buffer holding its incoming data. The buffer will then not be recycled
* until it is returned to CM with CMreturn_buffer().
* \param cm The CManager in which the handler was called.
* \param data The base address of the data (I.E. the message parameter to
* the CMHandlerFunc).
* \return NULL on error, otherwise returns the data parameter.
*/
extern void *CMtake_buffer (CManager cm, void *data);
/*!
* return a buffer of incoming data.
*
* This call recycles a data buffer that the application has taken control
* of through CMtake_buffer().
* \param cm The CManager in which the handler was called.
* \param data The base address of the data (I.E. same value that was passed
* to CMtake_buffer().
*/
extern void CMreturn_buffer (CManager cm, void *data);
#include "cm_transport.h"
/*!
* The prototype for a non-CM message handler.
*
* Functions matching of this prototype can be registered with
* CMregister_non_CM_message_handler().
* \param conn The CMConnection on which the message is available.
* \param header The first 4 bytes of the message, encoded as an integer.
* \return 0 if the message was completely handled.
* Otherwise return the number of additional bytes necessary.
*/
typedef int (*CMNonCMHandler) (CMConnection conn, CMTransport transport,
char *buffer, size_t length);
/*!
* register a handler for raw (non-CM) messages.
*
* CM, like may other message layers, embeds a unique value in the first 4
* bytes of the incoming message to identify it as a CM message. CM
* actually has several sets of identifying 4-byte values that it recognizes
* as CM-internal messages. This interface can be used to add to that set
* to include non-CM messages (such as IIOP, HTTP, etc.).
* \param header The 4 bytes that identify (encoded as an integer) that
* identify the messages to be handled.
* \param handler The handler to be called when messages with this header
* arrive.
* \note Registration is not CManager-specific, but apply to all CManagers
* in the address space (ugly).
* \warning Don't do this at home kids! This API is not complete enough to
* actually implement something like IIOP externally, but it's the thought
* that counts.
*/
/*NOLOCK*/
extern void
CMregister_non_CM_message_handler (int header, CMNonCMHandler handler);
/*!
* register a handler for CM messages that don't match registered handlers.
*
*/
typedef void (*CMUnregCMHandler) (CMConnection conn, char *format_name);
/*NOLOCK*/
extern void
CMregister_invalid_message_handler (CManager cm, CMUnregCMHandler handler);
/*!
* return the pointer to the static transport services structure.
*
* All transports share a set of basic services provided by CM, whose function
* pointers are available through this structure.
*
* \return returns the pointer to the services structure.
*/
/*NOLOCK*/
extern CMtrans_services
CMget_static_trans_services ();
/*!
* return the pointer to a CMConnection's transport data.
*
* Think of this structure as the cross-product of a transport and CMConnection.
* Transport functions use this structure to store per-connection data.
*
* \return returns the pointer to the transport data structure.
*/
extern void*
CMget_transport_data (CMConnection conn);
/*!
* add a task (function) to be executed occasionally.
*
* \param cm The CManager to which the task is added.
* \param func The function to be called occasionally.
* \param client_data An uninterpreted value that is passed to the function
* when it is called.
* CM poll functions are called after each round of message delivery. I.E.
* once per call to CMpoll_network() if that function is used.
*/
extern void
CMadd_poll (CManager cm, CMPollFunc func, void *client_data);
/*!
* add a task (function) to be executed with a specified periodicity.
*
* \param cm The CManager to which the task is added.
* \param period_sec The number of whole seconds of the period.
* \param period_usec The number of additional microseconds of the period.
* \param func The function to be called periodically.
* \param client_data An uninterpreted value that is passed to the function
* when it is called.
* \return a CMTaskHandle which can be used to remove the task.
* \note CM does not guarantee a particular periodicity, it merely applies
* its best efforts. I.E. It will not block wait in select() past the
* timeout period for the next task. However handlers may run long and I/O
* may intervene to delay the task execution. The task will be executed
* when the first opportunity arises after it is scheduled. After execution
* is complete, the next execution will be scheduled based upon the actual
* execution time of the current invocation (not when it was scheduled to be
* executed).
*/
extern CMTaskHandle
CMadd_periodic_task (CManager cm, int period_sec, int period_usec,
CMPollFunc func, void *client_data);
/*!
* add a task (function) to be executed at a later time.
*
* \param cm The CManager to which the task is added.
* \param secs The number of whole seconds to delay the task.
* \param usecs The number of additional microseconds to delay the task.
* \param func The function to be called after the delay.
* \param client_data An uninterpreted value that is passed to the function
* when it is called.
* \return a CMTaskHandle which can be used to remove the task (only before
* it executes).
* \note CM does not guarantee a particular delay, it merely applies
* its best efforts. I.E. It will not block wait in select() past the
* timeout period for the next task. However handlers may run long and I/O
* may intervene to delay the task execution. The task will be executed
* when the first opportunity arises after it is scheduled.
*/
extern CMTaskHandle
CMadd_delayed_task (CManager cm, int secs, int usecs, CMPollFunc func,
void *client_data);
/*!
* remove a registered periodic or delayed task.
*
* \param handle The handle to the task to remove.
*/
extern void
CMremove_task (CMTaskHandle handle);
/*!
* add a task (function) to be called when the CM is shut down.
*
* \param cm The CManager to which a shutdown task is added.
* \param func The function to be called upon shutdown.
* \param client_data An uninterpreted value that is passed to the function
* when it is called.
* \param task_type Should be either SHUTDOWN_TASK or FREE_TASK
*
* Multiple shutdown tasks can be added to the same CM and they are called
* in the order registered. There is currently no API for removing them.
*/
extern void
CMadd_shutdown_task (CManager cm, CMPollFunc func, void *client_data, int task_type);
/*!
* task type for CMadd_shutdown_task. NO_TASK is used internally
*/
#define NO_TASK 0
/*!
* task type for CMadd_shutdown_task. SHUTDOWN_TASKs will be called at first close.
*/
#define SHUTDOWN_TASK 1
/*!
* task type for CMadd_shutdown_task. FREE_TASKs will be called when the CM reference count reaches zero.
*/
#define FREE_TASK 2
/*!
* add a task to be executed with a particular periodicity.
*
* \param cm The CManager which should execute the task.
* \param period The period of the task in microseconds.
* \param func The function to be called.
* \param client_data An uninterpreted value that is passed to the function
* when it is called.
* \return a CMTaskHandle which can be used to remove the task.
* \deprecated Use CMadd_periodic_task().
*/
extern CMTaskHandle
CMadd_periodic (CManager cm, long period, CMPollFunc func,
void *client_data);
/*!
* remove a registered periodic task.
*
* \param handle The handle to the task to remove.
* \deprecated Use CMremove_task()
*/
extern void
CMremove_periodic (CMTaskHandle handle);
/*!
* sleep for a given number of seconds.
*
* Unlike system sleep() calls, CMsleep() will continue to handle network
* messages during the sleep time. In particular, if CMsleep is called by
* the network handler thread or in a single threaded program, then it will
* enter a network handling loop until the time has elapsed. If called by
* other than the network handler thread in a multithread application, then
* it will suspend on a thread condition wait until the time has elapsed.
* \param cm The CManager upon which to sleep.
* \param secs The number of seconds for which to sleep.
*/
extern void
CMsleep (CManager cm, int secs);
/*!
* sleep for a given number of microseconds.
*
* Unlike system sleep() calls, CMusleep() will continue to handle network
* messages during the sleep time. In particular, if CMusleep is called by
* the network handler thread or in a single threaded program, then it will
* enter a network handling loop until the time has elapsed. If called by
* other than the network handler thread in a multithread application, then
* it will suspend on a thread condition wait until the time has elapsed.
* \param cm The CManager upon which to sleep.
* \param usecs The number of microseconds for which to sleep.
*/
extern void
CMusleep (CManager cm, int usecs);
/*!
* handle one round of network events
*
* \param cm The CManager for which to handle events.
* CMpoll_network()} is one of the basic <b>network event</b> handling calls
* in CM. A CM network event is a basic communications occurrence, such as
* a connection request or message arrival. The routine CMpoll_network()
* essentially polls the network and handles some pending messages before
* returning.
* \note Not all pending messages will be handled, but generally one message
* will be handled for each connection upon which input is pending.
*/
extern
void CMpoll_network (CManager cm);
/*!
* handle network events until shutdown.
*
* \param cm The CManager for which to handle events.
* CMrun_network()} is one of the basic <b>network event</b> handling calls
* in CM. A CM network event is a basic communications occurrence, such as
* a connection request or message arrival. The routine CMrun_network()
* essentially handles network events until the CManager is shutdown.
*/
extern
void CMrun_network (CManager cm);
/*!
* The prototype for a CM select handling function.
*
* CM allows application-routines matching this prototype to be registered
* and called when a particular file descriptor has data available to read.
* \param param1 is the value specified as param1 in the CM_fd_add_select() call.
* \param param2 is the value specified as param2 in the CM_fd_add_select() call.
*/
typedef void (*select_func) (void *param1, void*param2);
/*!
* Register an application routine to be called with a particular
* file descriptor has data available for read.
*
* \param cm The CManager with which this handler is to be registered.
* \param fd The file descriptor to be monitored.
* \param handler_func The function to be called when data is available.
* \param param1 The value to be passed as param1 to the handler_func.
* \param param2 The value to be passed as param2 to the handler_func.
*/
extern void
CM_fd_add_select (CManager cm, SOCKET fd, select_func handler_func,
void *param1, void *param2);
/*!
* allocate a new CM condition value.
*
* \param cm the CManager value in which to allocate the condition.
* \param dep the CMConnection value upon which the condition depends.
* \return an integer value representing a CM condition.
* \note CM condition values are used to cause a thread or program to wait
* for a particular situation, usually for a message response to arrive.
* In this case the condition value is acquired before sending the request
* message, integer condition value is sent as part of the request and
* returned in the response. The response handler then does a
* CMCondition_signal() as part of its operation.
* \note The dep CMConnection value is used in error handling. In
* particular, if that connection dies or is closed, the condition will be
* marked as <b>failed</b> and the corresponding CMCondition_wait() will
* return. Thus if the situation in which the condition is used relies upon
* the continued operation of a connection (such as waiting for a response),
* then that connection should be specified as the dep parameter in this
* call. If there is no such reliance, dep can be NULL.
*/
extern int CMCondition_get (CManager cm, CMConnection dep);
/*!
* wait for a CM condition value.
*
* \param cm the CManager value in which the condition was allocated.
* \param condition the condition upon which to wait.
* \return
* - 1 if the condition was signalled normally.
* - 0 if the CMConnection specified as dep in the CMCondition_get()
* call was closed.
* \note CM condition values are used to cause a thread or program to wait
* for a particular situation, usually for a message response to arrive.
* \note CMCondition_wait() is useful because it does the "right thing" in
* both single-threaded and multi-threaded applications. In single-threaded
* applications it enters a network-handling loop until the condition has
* been signaled. In applications with a network handler thread, it checks
* to see if it is being executed by that handler thread. If it is *not*,
* then it does a thread condition wait to suspect the thread. If it is
* being executed by the network handler thread, then it also enters a
* network-handling loop until the condition has been signaled.
* \warning The condition value is considered 'free'd upon return from
* CMCondition_wait() and should not be used in any subsequent call
* (including calls to CMCondition_get_client_data(), etc.).
*/
extern int CMCondition_wait (CManager cm, int condition);
/*!
* signal a CM condition value.
*
* \param cm the CManager value in which the condition was allocated.
* \param condition the condition to be signaled.
* \note CM condition values are used to cause a thread or program to wait
* for a particular situation, usually for a message response to arrive.
* \note CMCondition_signal() notifies CM that the situation needed to
* satisfy a particular condition variable has occurred and any waiting
* thread should awaken.
*/
extern void CMCondition_signal (CManager cm, int condition);
/*!
* set the client_data associated with a condition value.
*
* \param cm the CManager value in which the condition is allocated.
* \param condition the condition with which the client_data should be
* associated.
* \param client_data the value to be associated with the condition.
* \note The client_data value is not interpreted by CM, but instead
* provides a mechanism through which information can be conveyed between
* the requesting thread and response handler. In a typical usage, the
* requesting site sets the client_data to the address of storage for a
* return value. The response handler then uses
* CMCondition_get_client_data() to access that address and store the return
* value in the appropriate location.
* \warning Calls to CMCondition_set_client_data() should occur between the
* call to CMCondition_alloc() and CMCondition_wait(). The condition value
* is considered 'free'd upon return from CMCondition_wait() and should not
* be used in any subsequent call. To avoid possible race conditions, calls
* to CMCondition_set_client_data() should also occur before the CMwrite of
* the request to ensure that the response doesn't arrive before the client
* data is set.
*/
extern void CMCondition_set_client_data (CManager cm, int condition,
void *client_data);
/*!
* get the client_data associated with a condition value.
*
* \param cm the CManager value in which the condition is allocated.
* \param condition the condition to query for client_data.
* \return the client_data value associated with the condition.
* \note The client_data value is not interpreted by CM, but instead
* provides a mechanism through which information can be conveyed between
* the requesting thread and response handler. In a typical usage, the
* requesting site sets the client_data to the address of storage for a
* return value. The response handler then uses
* CMCondition_get_client_data() to access that address and store the return
* value in the appropriate location.
* \warning Calls to CMCondition_get_client_data() should generally occur
* in the response handler (as opposed to after CMCondition_wait()). The
* condition value is considered 'free'd upon return from CMCondition_wait()
* and should not be used in any subsequent call.
*/
extern void *CMCondition_get_client_data (CManager cm, int condition);
/*!
* test whether or not a particular condition has been signaled.
*
* \param cm the CManager value in which the condition is allocated.
* \param condition the condition to test.
* \return boolean value representing whether or not the condition has been
* signaled.
* This call essentially provides a mechanism of examining the state of a
* condition without blocking on CMCondition_wait().
* \warning This call should not be used on a condition after
* a CMCondition_wait() has been performed.
*/
extern int CMCondition_has_signaled (CManager cm, int condition);
/*!
* test whether or not a particular condition has failed.
*
* \param cm the CManager value in which the condition is allocated.
* \param condition the condition to test.
* \return boolean value representing whether or not the condition has
* failed (I.E. its dependent connection has been closed.)
* This call essentially provides a mechanism of examining the state of a
* condition without blocking on CMCondition_wait().
* \warning This call should not be used on a condition after
* a CMCondition_wait() has been performed.
*/
extern int CMCondition_has_failed (CManager cm, int condition);
/** @defgroup malloc CM memory allocation functions
*
* This group of functions is used to manage CM-returned memory.
* They are provided to handle the eventuality when CM uses its own memory
* manager. That hasn't happened yet, so these are identical to realloc,
* malloc and free.
*/
/*!
* reallocate a chunk of memory
*
* \param ptr the memory to reallocate
* \param size the new size
* \return a pointer to the new block
*/
/*NOLOCK*/
extern void* CMrealloc (void *ptr, long size);
/*!
* allocate a chunk of memory
*
* \param size the requested size
* \return a pointer to the new block