1 //%2003////////////////////////////////////////////////////////////////////////
3 // Copyright (c) 2000, 2001, 2002 BMC Software, Hewlett-Packard Development
4 // Company, L. P., IBM Corp., The Open Group, Tivoli Systems.
5 // Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L. P.;
6 // IBM Corp.; EMC Corporation, The Open Group.
8 // Permission is hereby granted, free of charge, to any person obtaining a copy
9 // of this software and associated documentation files (the "Software"), to
10 // deal in the Software without restriction, including without limitation the
11 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
12 // sell copies of the Software, and to permit persons to whom the Software is
13 // furnished to do so, subject to the following conditions:
15 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
16 // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
17 // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
18 // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
19 // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
21 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 //==============================================================================
26 // Author: Mike Day (mdday@us.ibm.com) << Tue Mar 19 13:19:24 2002 mdd >>
30 //%/////////////////////////////////////////////////////////////////////////////
32 #include "ModuleController.h"
33 #include <Pegasus/Common/MessageLoader.h> //l10n
35 PEGASUS_NAMESPACE_BEGIN
39 ModuleController::callback_handle * ModuleController::callback_handle::_head;
40 const int ModuleController::callback_handle::BLOCK_SIZE = 20;
41 Mutex ModuleController::callback_handle::_alloc_mut;
47 void * ModuleController::callback_handle::operator new(size_t size)
49 if( size != sizeof(callback_handle))
50 return ::operator new(size);
51 _alloc_mut.lock(pegasus_thread_self());
52 callback_handle *node = _head;
54 _head = reinterpret_cast<callback_handle *>(node->_parm);
57 callback_handle *block =
58 reinterpret_cast<callback_handle *>(::operator new(BLOCK_SIZE * sizeof(callback_handle)));
60 for(i = 1; i < BLOCK_SIZE - 1; ++i)
61 block[i]._parm = & block[i + 1];
62 block[BLOCK_SIZE - 1]._parm = NULL;
71 void ModuleController::callback_handle::operator delete(void *dead, size_t size)
75 if(size != sizeof(callback_handle))
77 ::operator delete(dead);
80 callback_handle *node = reinterpret_cast<callback_handle *>(dead);
81 _alloc_mut.lock(pegasus_thread_self());
88 pegasus_module::module_rep::module_rep(ModuleController *controller,
91 Message * (*receive_message)(Message *, void *),
92 void (*async_callback)(Uint32, Message *, void *),
93 void (*shutdown_notify)(Uint32 code, void *))
94 : Base ( pegasus_internal_identity(peg_credential_types::MODULE) ),
96 _controller(controller),
100 _module_address(module_address)
103 if(receive_message != NULL)
104 _receive_message = receive_message;
106 _receive_message = default_receive_message;
107 if(async_callback != NULL)
108 _async_callback = async_callback;
110 _async_callback = default_async_callback;
111 if(shutdown_notify != NULL)
112 _shutdown_notify = shutdown_notify;
114 _shutdown_notify = default_shutdown_notify;
118 pegasus_module::module_rep::~module_rep(void)
120 _send_shutdown_notify();
123 Message * pegasus_module::module_rep::module_receive_message(Message *msg)
126 _thread_safety.lock(pegasus_thread_self());
127 try { ret = _receive_message(msg, _module_address); }
130 _thread_safety.unlock();
133 _thread_safety.unlock();
137 void pegasus_module::module_rep::_send_async_callback(Uint32 msg_handle, Message *msg, void *parm)
139 _thread_safety.lock(pegasus_thread_self());
140 try { _async_callback(msg_handle, msg, parm); }
141 catch(...) { _thread_safety.unlock(); throw; }
142 _thread_safety.unlock();
145 void pegasus_module::module_rep::_send_shutdown_notify(void)
147 _thread_safety.lock(pegasus_thread_self());
148 if(_reference_count.value() == 0 )
150 if( _shutting_down == 0 )
153 _shutdown_notify(_reference_count.value(), _module_address);
154 _async_callback = closed_async_callback;
155 _receive_message = closed_receive_message;
158 _thread_safety.unlock();
162 Boolean pegasus_module::module_rep::authorized()
167 Boolean pegasus_module::module_rep::authorized(Uint32 operation)
172 Boolean pegasus_module::module_rep::authorized(Uint32 index, Uint32 operation)
178 pegasus_module::pegasus_module(ModuleController *controller,
180 void *module_address,
181 Message * (*receive_message)(Message *, void *),
182 void (*async_callback)(Uint32, Message *, void *),
183 void (*shutdown_notify)(Uint32 code, void *))
185 _rep = new module_rep(controller,
191 _allowed_operations = ModuleController::GET_CLIENT_HANDLE |
192 ModuleController::REGISTER_MODULE |
193 ModuleController::DEREGISTER_MODULE |
194 ModuleController::FIND_SERVICE |
195 ModuleController::FIND_MODULE_IN_SERVICE |
196 ModuleController::GET_MODULE_REFERENCE |
197 ModuleController::MODULE_SEND_WAIT |
198 ModuleController::MODULE_SEND_WAIT_MODULE |
199 ModuleController::MODULE_SEND_ASYNC |
200 ModuleController::MODULE_SEND_ASYNC_MODULE |
201 ModuleController::BLOCKING_THREAD_EXEC |
202 ModuleController::ASYNC_THREAD_EXEC;
205 pegasus_module::pegasus_module(const pegasus_module & mod)
207 mod._rep->reference();
211 pegasus_module::~pegasus_module(void)
214 _send_shutdown_notify();
215 if( 0 == _rep->reference_count())
219 Boolean pegasus_module::authorized(Uint32 operation)
224 Boolean pegasus_module::authorized()
230 pegasus_module & pegasus_module::operator= (const pegasus_module & mod)
234 if ( _rep->reference_count() == 0 )
241 Boolean pegasus_module::operator== (const pegasus_module & mod) const
243 if( mod._rep == _rep )
249 Boolean pegasus_module::operator == (const String & mod) const
251 if(_rep->get_name() == mod)
257 Boolean pegasus_module::operator == (const void *mod) const
259 if ( (reinterpret_cast<const pegasus_module *>(mod))->_rep == _rep)
264 const String & pegasus_module::get_name(void) const
266 return _rep->get_name();
270 Boolean pegasus_module::query_interface(const String & class_id,
271 void **object_ptr) const
273 PEGASUS_ASSERT(object_ptr != NULL);
274 if( class_id == _rep->get_name())
276 *object_ptr = _rep->get_module_address();
283 Message * pegasus_module::_receive_message(Message *msg)
285 return _rep->module_receive_message(msg);
288 void pegasus_module::_send_async_callback(Uint32 msg_handle, Message *msg, void *parm)
290 _rep->_send_async_callback(msg_handle, msg, parm);
293 void pegasus_module::_send_shutdown_notify(void)
295 _rep->_send_shutdown_notify();
298 Boolean pegasus_module::_shutdown(void)
300 _send_shutdown_notify();
306 const Uint32 ModuleController::GET_CLIENT_HANDLE = 0x00000001;
307 const Uint32 ModuleController::REGISTER_MODULE = 0x00000002;
308 const Uint32 ModuleController::DEREGISTER_MODULE = 0x00000004;
309 const Uint32 ModuleController::FIND_SERVICE = 0x00000008;
310 const Uint32 ModuleController::FIND_MODULE_IN_SERVICE = 0x00000010;
311 const Uint32 ModuleController::GET_MODULE_REFERENCE = 0x00000020;
312 const Uint32 ModuleController::MODULE_SEND_WAIT = 0x00000040;
313 const Uint32 ModuleController::MODULE_SEND_WAIT_MODULE = 0x00000040;
314 const Uint32 ModuleController::MODULE_SEND_ASYNC = 0x00000080;
315 const Uint32 ModuleController::MODULE_SEND_ASYNC_MODULE = 0x00000080;
316 const Uint32 ModuleController::BLOCKING_THREAD_EXEC = 0x00000100;
317 const Uint32 ModuleController::ASYNC_THREAD_EXEC = 0x00000200;
318 const Uint32 ModuleController::CLIENT_SEND_WAIT = 0x00000400;
319 const Uint32 ModuleController::CLIENT_SEND_WAIT_MODULE = 0x00000400;
320 const Uint32 ModuleController::CLIENT_SEND_ASYNC = 0x00000800;
321 const Uint32 ModuleController::CLIENT_SEND_ASYNC_MODULE = 0x00000800;
322 const Uint32 ModuleController::CLIENT_BLOCKING_THREAD_EXEC =0x00001000;
323 const Uint32 ModuleController::CLIENT_ASYNC_THREAD_EXEC = 0x00001000;
324 const Uint32 ModuleController::CLIENT_SEND_FORGET = 0x00002000;
325 const Uint32 ModuleController::CLIENT_SEND_FORGET_MODULE = 0x00002000;
326 const Uint32 ModuleController::MODULE_SEND_FORGET = 0x00004000;
327 const Uint32 ModuleController::MODULE_SEND_FORGET_MODULE = 0x00004000;
330 Boolean ModuleController::client_handle::authorized()
335 Boolean ModuleController::client_handle::authorized(Uint32 operation)
341 Boolean ModuleController::client_handle::authorized(Uint32 index, Uint32 operation)
347 // NOTE: "destroy" is defined in <memory> on HP-UX and must not be redefined
348 static struct timeval createTime = {0, 50000};
349 static struct timeval destroyTime = {15, 0};
350 static struct timeval deadlockTime = {5, 0};
352 ModuleController::ModuleController(const char *name )
353 :Base(name, MessageQueue::getNextQueueId(),
354 module_capabilities::module_controller |
355 module_capabilities::async),
357 _internal_module(this, String("INTERNAL"), this, NULL, NULL, NULL)
362 // ModuleController::ModuleController(const char *name ,
363 // Sint16 min_threads,
364 // Sint16 max_threads,
365 // struct timeval & create_thread,
366 // struct timeval & destroy_thread,
367 // struct timeval & deadlock)
368 // :Base(name, MessageQueue::getNextQueueId(),
369 // module_capabilities::module_controller |
370 // module_capabilities::async),
372 // _thread_pool(min_threads + 1,
373 // name, min_threads,
382 ModuleController::~ModuleController()
385 pegasus_module *module;
389 module = _modules.remove_first();
393 module = _modules.remove_first();
402 // called by a module to register itself, returns a handle to the controller
403 ModuleController & ModuleController::register_module(const String & controller_name,
404 const String & module_name,
405 void *module_address,
406 Message * (*receive_message)(Message *, void *),
407 void (*async_callback)(Uint32, Message *, void *),
408 void (*shutdown_notify)(Uint32, void *),
409 pegasus_module **instance)
410 throw(AlreadyExistsException, IncompatibleTypesException)
413 pegasus_module *module ;
414 ModuleController *controller;
417 Array<Uint32> services;
419 MessageQueue *message_queue = MessageQueue::lookup(controller_name.getCString());
421 if ((message_queue == NULL) || ( false == message_queue->isAsync() ))
423 throw IncompatibleTypesException();
426 MessageQueueService *service = static_cast<MessageQueueService *>(message_queue);
427 if( (service == NULL) || ! ( service->get_capabilities() & module_capabilities::module_controller ))
429 throw IncompatibleTypesException();
432 controller = static_cast<ModuleController *>(service);
437 // see if the module already exists in this controller.
438 _module_lock lock(&(controller->_modules));
440 module = controller->_modules.next(0);
441 while(module != NULL )
443 if(module->get_name() == module_name )
446 //throw AlreadyExistsException("module \"" + module_name + "\"");
447 MessageLoaderParms parms("Common.ModuleController.MODULE",
450 throw AlreadyExistsException(parms);
452 module = controller->_modules.next(module);
457 // now reserve this module name with the meta dispatcher
460 RegisteredModule *request =
461 new RegisteredModule(controller->get_next_xid(),
464 controller->getQueueId(),
467 request->dest = CIMOM_Q_ID;
469 AsyncReply * response = controller->SendWait(request);
470 if( response != NULL)
471 result = response->result;
475 if ( result == async_results::MODULE_ALREADY_REGISTERED){
477 //throw AlreadyExistsException("module \"" + module_name + "\"");
478 MessageLoaderParms parms("Common.ModuleController.MODULE",
481 throw AlreadyExistsException(parms);
485 // the module does not exist, go ahead and create it.
486 module = new pegasus_module(controller,
493 controller->_modules.insert_last(module);
502 Boolean ModuleController::deregister_module(const String & module_name)
506 DeRegisteredModule *request =
507 new DeRegisteredModule(get_next_xid(),
512 request->dest = _meta_dispatcher->getQueueId();
514 AsyncReply * response = SendWait(request);
519 pegasus_module *module;
521 _module_lock lock(&_modules);
522 module = _modules.next(0);
523 while(module != NULL )
525 if( module->get_name() == module_name)
527 _modules.remove_no_lock(module);
530 module = _modules.next(module);
535 Boolean ModuleController::verify_handle(pegasus_module *handle)
537 pegasus_module *module;
539 // ATTN change to use authorization and the pegasus_id class
540 // << Fri Apr 5 12:43:19 2002 mdd >>
541 if( handle->_rep->_module_address == (void *)this)
544 _module_lock lock(&_modules);
546 module = _modules.next(0);
547 while(module != NULL)
549 if ( module == handle)
553 module = _modules.next(module);
558 // given a name, find a service's queue id
559 Uint32 ModuleController::find_service(const pegasus_module & handle,
560 const String & name) throw(Permission)
563 if ( false == verify_handle(const_cast<pegasus_module *>(&handle)) )
564 throw Permission(pegasus_thread_self());
565 Array<Uint32> services;
566 Base::find_services(name, 0, 0, &services);
567 return( services[0]);
571 // returns the queue ID of the service hosting the named module,
574 Uint32 ModuleController::find_module_in_service(const pegasus_module & handle,
576 throw(Permission, IPCException)
578 if ( false == verify_handle(const_cast<pegasus_module *>(&handle)))
579 throw(Permission(pegasus_thread_self()));
584 FindModuleInService *request =
585 new FindModuleInService(get_next_xid(),
588 _meta_dispatcher->getQueueId(),
590 request->dest = _meta_dispatcher->getQueueId();
591 FindModuleInServiceResponse * response =
592 static_cast<FindModuleInServiceResponse *>(SendWait(request));
593 if( response != NULL)
594 result = response->_module_service_queue;
603 pegasus_module * ModuleController::get_module_reference(const pegasus_module & my_handle,
604 const String & module_name)
607 if ( false == verify_handle(const_cast<pegasus_module *>(&my_handle)))
608 throw(Permission(pegasus_thread_self()));
610 pegasus_module *module, *ref = NULL;
611 _module_lock lock(&_modules);
612 module = _modules.next(0);
613 while(module != NULL)
615 if(module->get_name() == module_name)
617 ref = new pegasus_module(*module);
620 module = _modules.next(module);
626 AsyncReply *ModuleController::_send_wait(Uint32 destination_q,
627 AsyncRequest *request)
629 request->dest = destination_q;
630 AsyncReply *reply = Base::SendWait(request);
635 // sendwait to another service
636 AsyncReply * ModuleController::ModuleSendWait(const pegasus_module & handle,
637 Uint32 destination_q,
638 AsyncRequest *request)
639 throw(Permission, IPCException)
641 if ( false == verify_handle(const_cast<pegasus_module *>(&handle)))
642 throw(Permission(pegasus_thread_self()));
644 return _send_wait(destination_q, request);
647 AsyncReply *ModuleController::_send_wait(Uint32 destination_q,
648 const String & destination_module,
649 AsyncRequest *message)
651 AsyncModuleOperationStart *request =
652 new AsyncModuleOperationStart(get_next_xid(),
660 request->dest = destination_q;
661 AsyncModuleOperationResult *response =
662 static_cast<AsyncModuleOperationResult *>(SendWait(request));
666 if (response != NULL && response->getType() == async_messages::ASYNC_MODULE_OP_RESULT )
668 ret = static_cast<AsyncReply *>(response->get_result());
669 //clear the request out of the envelope so it can be deleted by the module
671 request->get_action();
678 // sendwait to another module controlled by another service.
679 // throws Deadlock() if destination_q is this->queue_id
680 AsyncReply * ModuleController::ModuleSendWait(const pegasus_module & handle,
681 Uint32 destination_q,
682 const String & destination_module,
683 AsyncRequest *message)
684 throw(Permission, Deadlock, IPCException)
686 if ( false == verify_handle(const_cast<pegasus_module *>(&handle)))
687 throw(Permission(pegasus_thread_self()));
689 return _send_wait(destination_q, destination_module, message);
692 void ModuleController::_async_handleEnqueue(AsyncOpNode *op,
697 ModuleController *myself = static_cast<ModuleController *>(q);
698 Message *request = op->get_request();
699 Message *response = op->get_response();
701 if( request && (! (request->getMask() & message_mask::ha_async)))
702 throw TypeMismatchException();
704 if( response && (! (response->getMask() & message_mask::ha_async) ))
705 throw TypeMismatchException();
708 myself->return_op(op);
712 // get rid of the module wrapper
713 if( request && request->getType() == async_messages::ASYNC_MODULE_OP_START )
715 (static_cast<AsyncMessage *>(request))->op = NULL;
716 AsyncModuleOperationStart *rq = static_cast<AsyncModuleOperationStart *>(request);
717 request = rq->get_action();
718 request->setRouting(routing = rq->getRouting());
722 // get rid of the module wrapper
723 if(response && response->getType() == async_messages::ASYNC_MODULE_OP_RESULT )
725 (static_cast<AsyncMessage *>(response))->op = NULL;
726 AsyncModuleOperationResult *rp = static_cast<AsyncModuleOperationResult *>(response);
727 response = rp->get_result();
728 response->setRouting(routing = rp->getRouting());
732 callback_handle *cb = reinterpret_cast<callback_handle *>(parm);
734 cb->_module->_send_async_callback(routing, response, cb->_parm);
741 // send an async message to a service asynchronously
742 Boolean ModuleController::ModuleSendAsync(const pegasus_module & handle,
744 Uint32 destination_q,
745 AsyncRequest *message,
747 throw(Permission, IPCException)
749 //printf("verifying handle %p, controller at %p \n", &handle, this);
751 if ( false == verify_handle(const_cast<pegasus_module *>(&handle)))
752 throw(Permission(pegasus_thread_self()));
754 if (message->op == NULL)
756 message->op = get_op();
757 message->op->put_request(message);
761 callback_handle *cb = new callback_handle(const_cast<pegasus_module *>(&handle),
764 message->setRouting(msg_handle);
765 message->resp = getQueueId();
766 message->block = false;
767 message->dest = destination_q;
768 return SendAsync(message->op,
770 _async_handleEnqueue,
775 // send a message to a module within another service asynchronously
776 Boolean ModuleController::ModuleSendAsync(const pegasus_module & handle,
778 Uint32 destination_q,
779 const String & destination_module,
780 AsyncRequest *message,
782 throw(Permission, IPCException)
785 if ( false == verify_handle(const_cast<pegasus_module *>(&handle)))
786 throw(Permission(pegasus_thread_self()));
788 AsyncOpNode *op = get_op();
789 AsyncModuleOperationStart *request =
790 new AsyncModuleOperationStart(msg_handle,
797 request->dest = destination_q;
798 callback_handle *cb = new callback_handle(const_cast<pegasus_module *>(&handle), callback_parm);
801 _async_handleEnqueue,
807 Boolean ModuleController::_send_forget(Uint32 destination_q, AsyncRequest *message)
810 message->dest = destination_q;
811 return SendForget(message);
814 Boolean ModuleController::_send_forget(Uint32 destination_q,
815 const String & destination_module,
816 AsyncRequest *message)
819 AsyncOpNode *op = get_op();
820 message->dest = destination_q;
821 AsyncModuleOperationStart *request =
822 new AsyncModuleOperationStart(0,
829 return SendForget(request);
834 Boolean ModuleController::ModuleSendForget(const pegasus_module & handle,
835 Uint32 destination_q,
836 AsyncRequest *message)
837 throw(Permission, IPCException)
839 if(false == verify_handle(const_cast<pegasus_module *>( &handle)))
840 throw(Permission(pegasus_thread_self()));
842 return _send_forget(destination_q, message);
845 Boolean ModuleController::ModuleSendForget(const pegasus_module & handle,
846 Uint32 destination_q,
847 const String & destination_module,
848 AsyncRequest *message)
849 throw(Permission, IPCException)
851 if(false == verify_handle(const_cast<pegasus_module *>( &handle)))
852 throw(Permission(pegasus_thread_self()));
853 return _send_forget(destination_q,
860 void ModuleController::_blocking_thread_exec(
861 PEGASUS_THREAD_RETURN (PEGASUS_THREAD_CDECL *thread_func)(void *),
864 Semaphore *blocking_sem = new Semaphore(0);
865 _thread_pool->allocate_and_awaken(parm, thread_func, blocking_sem);
866 blocking_sem->wait();
871 void ModuleController::blocking_thread_exec(
872 const pegasus_module & handle,
873 PEGASUS_THREAD_RETURN (PEGASUS_THREAD_CDECL *thread_func)(void *),
874 void *parm) throw(Permission, Deadlock, IPCException)
876 if ( false == verify_handle(const_cast<pegasus_module *>(&handle)))
877 throw(Permission(pegasus_thread_self()));
878 _blocking_thread_exec(thread_func, parm);
883 void ModuleController::_async_thread_exec(
884 PEGASUS_THREAD_RETURN (PEGASUS_THREAD_CDECL *thread_func)(void *),
887 _thread_pool->allocate_and_awaken(parm, thread_func);
892 void ModuleController::async_thread_exec(const pegasus_module & handle,
893 PEGASUS_THREAD_RETURN (PEGASUS_THREAD_CDECL *thread_func)(void *),
894 void *parm) throw(Permission, Deadlock, IPCException)
896 if ( false == verify_handle(const_cast<pegasus_module *>(&handle)))
897 throw(Permission(pegasus_thread_self()));
898 _async_thread_exec(thread_func, parm);
901 void ModuleController::_handle_async_request(AsyncRequest *rq)
904 if( rq->getType() == async_messages::ASYNC_MODULE_OP_START)
906 // find the target module
907 pegasus_module *target;
908 Message *module_result = NULL;
911 _module_lock lock(&_modules);
912 target = _modules.next(0);
913 while(target != NULL)
915 if(target->get_name() == static_cast<AsyncModuleOperationStart *>(rq)->_target_module)
918 module_result = target->_receive_message(static_cast<AsyncModuleOperationStart *>(rq)->_act);
922 target = _modules.next(target);
927 if(module_result == NULL)
929 module_result = new AsyncReply(async_messages::REPLY,
930 static_cast<AsyncModuleOperationStart *>(rq)->_act->getKey(),
931 static_cast<AsyncModuleOperationStart *>(rq)->_act->getRouting(),
932 message_mask::ha_async | message_mask::ha_reply,
934 async_results::CIM_NAK,
939 AsyncModuleOperationResult *result =
940 new AsyncModuleOperationResult(rq->getKey(),
944 static_cast<AsyncModuleOperationStart *>(rq)->resp,
946 static_cast<AsyncModuleOperationStart *>(rq)->_target_module,
948 _complete_op_node(rq->op, 0, 0, 0);
951 Base::_handle_async_request(rq);
954 void ModuleController::_handle_async_callback(AsyncOpNode *op)
956 Base::_handle_async_callback(op);
960 ModuleController & ModuleController::get_client_handle(const pegasus_identity & id,
961 client_handle **handle)
962 throw(IncompatibleTypesException)
964 return get_client_handle(PEGASUS_QUEUENAME_CONTROLSERVICE,
970 // called by a non-module client to get the interface and authorization to use the controller
972 ModuleController & ModuleController::get_client_handle(const char *controller,
973 const pegasus_identity & id,
974 client_handle **handle)
975 throw(IncompatibleTypesException)
981 Array<Uint32> services;
982 MessageQueue *message_queue = MessageQueue::lookup(controller);
984 if ((message_queue == NULL) || ( false == message_queue->isAsync() ))
986 throw IncompatibleTypesException();
989 MessageQueueService *service = static_cast<MessageQueueService *>(message_queue);
990 if( (service == NULL) || ! ( service->get_capabilities() & module_capabilities::module_controller ))
992 throw IncompatibleTypesException();
995 ModuleController *_controller = static_cast<ModuleController *>(service);
996 if(true == const_cast<pegasus_identity &>(id).authenticate())
997 *handle = new client_handle(id);
1001 return *_controller;
1005 void ModuleController::return_client_handle(client_handle *handle)
1007 if( true == handle->reference_count.DecAndTestIfZero())
1012 // send a message to another service
1013 AsyncReply *ModuleController::ClientSendWait(const client_handle & handle,
1014 Uint32 destination_q,
1015 AsyncRequest *request)
1016 throw(Permission, IPCException)
1018 if( false == const_cast<client_handle &>(handle).authorized(CLIENT_SEND_WAIT))
1019 throw Permission(pegasus_thread_self());
1020 return _send_wait(destination_q, request);
1024 // send a message to another module via another service
1025 AsyncReply *ModuleController::ClientSendWait(const client_handle & handle,
1026 Uint32 destination_q,
1027 String & destination_module,
1028 AsyncRequest *request)
1029 throw(Permission, Deadlock, IPCException)
1031 if( false == const_cast<client_handle &>(handle).authorized(CLIENT_SEND_WAIT_MODULE))
1032 throw Permission(pegasus_thread_self());
1033 return _send_wait(destination_q, destination_module, request);
1037 // send an async message to another service
1038 Boolean ModuleController::ClientSendAsync(const client_handle & handle,
1040 Uint32 destination_q,
1041 AsyncRequest *message,
1042 void (*async_callback)(Uint32, Message *, void *) ,
1043 void *callback_parm)
1044 throw(Permission, IPCException)
1046 if( false == const_cast<client_handle &>(handle).authorized(CLIENT_SEND_ASYNC))
1047 throw Permission(pegasus_thread_self());
1049 pegasus_module *temp = new pegasus_module(this,
1050 String(PEGASUS_MODULENAME_TEMP),
1055 return ModuleSendAsync( *temp,
1063 // send an async message to another module via another service
1064 Boolean ModuleController::ClientSendAsync(const client_handle & handle,
1066 Uint32 destination_q,
1067 const String & destination_module,
1068 AsyncRequest *message,
1069 void (*async_callback)(Uint32, Message *, void *),
1070 void *callback_parm)
1071 throw(Permission, IPCException)
1073 if( false == const_cast<client_handle &>(handle).authorized(CLIENT_SEND_ASYNC_MODULE))
1074 throw Permission(pegasus_thread_self());
1076 pegasus_module *temp = new pegasus_module(this,
1077 String(PEGASUS_MODULENAME_TEMP),
1082 return ModuleSendAsync(*temp,
1092 Boolean ModuleController::ClientSendForget(const client_handle & handle,
1093 Uint32 destination_q,
1094 AsyncRequest *message)
1095 throw(Permission, IPCException)
1097 if( false == const_cast<client_handle &>(handle).authorized(CLIENT_SEND_FORGET))
1098 throw Permission(pegasus_thread_self());
1100 return _send_forget(destination_q, message);
1104 Boolean ModuleController::ClientSendForget(const client_handle & handle,
1105 Uint32 destination_q,
1106 const String & destination_module,
1107 AsyncRequest *message)
1108 throw(Permission, IPCException)
1110 if( false == const_cast<client_handle &>(handle).authorized(CLIENT_SEND_FORGET_MODULE))
1111 throw Permission(pegasus_thread_self());
1113 return _send_forget(destination_q, destination_module, message);
1116 void ModuleController::client_blocking_thread_exec(
1117 const client_handle & handle,
1118 PEGASUS_THREAD_RETURN (PEGASUS_THREAD_CDECL *thread_func)(void *),
1119 void *parm) throw(Permission, Deadlock, IPCException)
1121 if( false == const_cast<client_handle &>(handle).authorized(CLIENT_BLOCKING_THREAD_EXEC))
1122 throw Permission(pegasus_thread_self());
1123 _blocking_thread_exec(thread_func, parm);
1127 void ModuleController::client_async_thread_exec(
1128 const client_handle & handle,
1129 PEGASUS_THREAD_RETURN (PEGASUS_THREAD_CDECL *thread_func)(void *),
1130 void *parm) throw(Permission, Deadlock, IPCException)
1133 if( false == const_cast<client_handle &>(handle).authorized(CLIENT_ASYNC_THREAD_EXEC))
1134 throw Permission(pegasus_thread_self());
1135 _async_thread_exec(thread_func, parm);
1139 PEGASUS_NAMESPACE_END