Interprocess communication code default_client.c
This article is mainly some client-side agent related codes, mainly the creation of the agent, the acquisition of service name and feature name in the agent, etc
File path: \ distributedschedule_samgr_lite\samgr_endpoint\source\default_client.c
Bedding of data structure
The implementation of this part of the client needs some structures to support
saname is mainly the name of the service and feature
//Identify service name and function name struct SaName { const char *service; //name of service const char *feature; //name of feature }; //Header information of client agent struct IClientHeader { SaName key; //The ID of the sa, including the name of the service and the name of the feature SvcIdentity target; //Access address of the target (server) uint32 deadId; const IpcContext *context; //IPC communication context }; //Client proxy entry struct IClientEntry { //Interface inheritance INHERIT_IUNKNOWNENTRY(IClientProxy); }; #pragma pack(1) struct IDefaultClient { IClientHeader header; //Client proxy header IClientEntry entry; //Client proxy channel }; #pragma pack() //Default proxy entry static const IClientEntry DEFAULT_ENTRY = {CLIENT_IPROXY_BEGIN, .Invoke = ProxyInvoke, IPROXY_END};
Function implementation
1. Creation of client agent
This function is to create a client proxy, but it will get the relevant parameter interface. First, query the main endpoint for the access address of the specified service and function. If an invalid value is returned, the service and function do not exist or are not registered. If the query is successful, it will be used as the target address of the current client agent. Then use the factory method to create the corresponding client agent and update the members of the agent. Finally, register the death callback function and return the proxy interface.
Introduction to parameters:
- Context: IPC communication context
- Service: service name
- feature: function name
IUnknown *SAMGR_CreateIProxy(const IpcContext *context, const char *service, const char *feature) { //Send a request to query the access address of the specified service and function to the main endpoint through the endpoint of the current process SvcIdentity identity = QueryIdentity(context, service, feature); if (identity.handle == INVALID_INDEX) { //The access address returned is an invalid value return NULL; } //Use the factory method to create client proxies for services and functions IDefaultClient *client = SAMGR_CreateIClient(service, feature, sizeof(IClientHeader)); if (client == NULL) { //Failed to create through the creator. Apply for memory creation by yourself client = SAMGR_Malloc(sizeof(IDefaultClient)); if (client == NULL) { return NULL; } //Configure the default portal for the client agent client->entry = DEFAULT_ENTRY; } //Assign a value to the client header. An IClientHeader pointer is defined here for the convenience of assignment IClientHeader *header = &client->header; header->target = identity; //Specifies the access address of the target that the client agent is targeting //The key value is used to identify which service and function the current agent is associated with header->key.service = service; //Service name header->key.feature = feature; //Function name header->context = context; //IPC context of the current process, identifying the entry of IPC communication access //Register the death callback function, which is triggered when the process disconnects from the remote service (void)RegisterDeathCallback(context, identity, OnServiceExit, client, &header->deadId); IClientEntry *entry = &client->entry; //Assign a value to the function pointer in the client's entry entry->iUnknown.Invoke = ProxyInvoke; //Function of agent entry->iUnknown.AddRef = AddRef; //Increase reference count entry->iUnknown.Release = Release; //Reduce reference count //Get IUnknown interface object from entry return GET_IUNKNOWN(*entry); }
2. Get service and feature access addresses
Query the client proxy interface according to the service name and function name, and the proxy interface is associated with the access address of the service and function. Get the IDefaultClient member in the interface, and finally get the access address of services and functions from the member header field.
Parameter introduction:
- Service: service name
- feature: function name
SvcIdentity SAMGR_GetRemoteIdentity(const char *service, const char *feature) { SvcIdentity identity = {INVALID_INDEX, INVALID_INDEX, INVALID_INDEX}; //Find the specified proxy interface according to the service name and function name. If it exists, it returns; if it does not exist, it is created and returned IUnknown *iUnknown = SAMGR_FindServiceApi(service, feature); if (iUnknown == NULL) { return identity; } IClientProxy *proxy = NULL; //Query the subclass objects of the IUnknown interface of the specified version, and save the results in the proxy if (iUnknown->QueryInterface(iUnknown, CLIENT_PROXY_VER, (void **)&proxy) != EC_SUCCESS || proxy == NULL) { return identity; } //Gets the IDefaultClient member of the agent struct IDefaultClient *client = GET_OBJECT(proxy, struct IDefaultClient, entry.iUnknown); //Get the target address information in the header identity = client->header.target; //Release reference proxy->Release((IUnknown *)proxy); return identity; }
3. Get information in saname
We mentioned earlier that the name information of the service and feature is stored in the saname. This function is to obtain the information in the saname in the proxy interface. Because header.key is a data of saname type, here is the name of the service name and feature
SaName *SAMGR_GetSAName(const IUnknown *proxy) { //Gets the IDefaultClient member of the proxy interface IDefaultClient *client = GET_OBJECT(proxy, IDefaultClient, entry.iUnknown); //Returns the SaName information in the header return &(client->header.key); }
4. Compare whether the stored contents of the two key s are consistent
We know that the key stores the saname type structure information, mainly the service name and special certificate name. Sometimes the two keys may store the same information, but there are different structure name information, or the two variables need to be compared to see whether they are consistent. At this time, we define the function to judge whether the two can be consistent.
The main principle is based on the strcmp function in the basic function library of c language. Because the two variable information are arrays of char type, we can directly compare the corresponding strings in the structure.
int SAMGR_CompareSAName(const SaName *key1, const SaName *key2) { //If equal, return 0 if (key1 == key2) { return 0; } //Judge whether the service addresses of key1 and key2 are the same if (key1->service != key2->service) { //If not, the content pointed to is compared int ret = strcmp(key1->service, key2->service); if (ret != 0) { //Returns if not equal return ret; } } //The service s of key1 and key2 point to the same value //Compare whether the address pointed to by the feature is the same if (key1->feature == key2->feature) { return 0; } //The service cannot be NULL, but the subordinate functions of the service can be NULL. Therefore, it is necessary to determine whether the feature points to NULL if (key1->feature == NULL) { return -1; } if (key2->feature == NULL) { return 1; } //Compare what the feature pointer points to return strcmp(key1->feature, key2->feature); }
This is part of the code, and the rest will be supplemented later!