Changes to attempt to silence bcc64x
[ACE_TAO.git] / TAO / examples / Load_Balancing_persistent / Load_Balancer_i.cpp
blobbf502bed7b0f89dd4cf2744bcc85ab0056659293
1 #include "Load_Balancer_i.h"
2 #include <memory>
3 #include "ace/Hash_Map_Manager_T.h"
5 const char *rr_name_bind = "RR_Group";
6 // Name binding for the location of the Round Robin info in the mem pool
8 const char *random_name_bind = "Random_Group";
9 // Name binding for the location of the Random info in the mem pool
11 const char *flags_name_bind = "FLAGS";
12 // Name binding for the location of the flags info in the mem pool
14 const char *dll_name_bind = "DLL_LIST";
15 // Name binding for the DLL_LIst in the me_pool;
17 const char *server_id_name_bind = "server_id";
18 // Some cookie that is used for appending names
20 Object_Group_Factory_i::Object_Group_Factory_i (CORBA::ORB_ptr orb,
21 PortableServer::POA_ptr poa)
22 :orb_ (orb),
23 poa_ (PortableServer::POA::_duplicate (poa)),
24 random_groups_ (0),
25 rr_groups_ (0),
26 flags_ (0)
28 ACE_MMAP_Memory_Pool::OPTIONS options (ACE_DEFAULT_BASE_ADDR);
29 ACE_NEW (this->mem_pool_,
30 ALLOCATOR ("Mem_Pool",
31 "Mem_Pool",
32 &options));
35 Object_Group_Factory_i::~Object_Group_Factory_i ()
37 delete this->mem_pool_;
40 PortableServer::POA_ptr
41 Object_Group_Factory_i::_default_POA ()
43 return PortableServer::POA::_duplicate (this->poa_.in ());
47 Load_Balancer::Object_Group_ptr
48 Object_Group_Factory_i::make_round_robin (const char * id)
50 void *tmp_rr (0);
52 if (this->mem_pool_->find (rr_name_bind,
53 tmp_rr) == 0)
55 this->rr_groups_ = reinterpret_cast <HASH_MAP *> (tmp_rr);
57 else
59 void *hash_map = this->mem_pool_->malloc (sizeof (HASH_MAP));
61 if (hash_map == 0)
62 throw CORBA::NO_MEMORY ();
64 this->rr_groups_ = new (hash_map) HASH_MAP (this->mem_pool_);
66 // Bind it in the mem pool with a name
67 if (this->mem_pool_->bind (rr_name_bind,
68 (void *)this->rr_groups_) != 0)
70 ACE_ERROR_RETURN ((LM_ERROR,
71 "Unable to bind\n"),
72 0);
76 return this->make_group (0,
77 id);
80 void
81 Object_Group_Factory_i::unbind_round_robin (const char * id)
83 if (this->rr_groups_ == 0)
85 void *tmp_rr (0);
87 if (this->mem_pool_->find (rr_name_bind,
88 tmp_rr) == -1)
89 throw Load_Balancer::no_such_group ();
91 this->rr_groups_ = reinterpret_cast <HASH_MAP *> (tmp_rr);
94 char *int_id = 0;
96 // Throw an exception if not found in the HASH MAP
97 if (this->rr_groups_->find (const_cast<char *> (id),
98 this->mem_pool_) < 0)
99 throw Load_Balancer::no_such_group ();
101 // Unbind the entry
102 this->rr_groups_->unbind (const_cast<char *> (id),
103 int_id,
104 this->mem_pool_);
106 // Free the memory from the pool
107 this->mem_pool_->free (int_id - (ACE_OS::strlen (id) + 1));
109 // Change the FLAGS variable
110 if (this->flags_ == 0)
112 void *tmp_flags (0);
114 if (this->mem_pool_->find (flags_name_bind,
115 tmp_flags) == -1)
116 return;
118 this->flags_ = reinterpret_cast <CORBA::Short *> (tmp_flags);
121 // Bump down the flags value
122 --this->flags_;
125 Load_Balancer::Object_Group_ptr
126 Object_Group_Factory_i::make_random (const char * id)
128 void *tmp_random (0);
130 if (this->mem_pool_->find (random_name_bind, tmp_random) == 0)
132 this->random_groups_ = reinterpret_cast <HASH_MAP *> (tmp_random);
134 else
136 void *hash_map = this->mem_pool_->malloc (sizeof (HASH_MAP));
138 if (hash_map == 0)
139 throw CORBA::NO_MEMORY ();
141 this->random_groups_ = new (hash_map) HASH_MAP (this->mem_pool_);
143 // Bind it in the mem pool with a name
144 if (this->mem_pool_->bind (random_name_bind,
145 (void *)this->random_groups_) != 0)
147 ACE_ERROR_RETURN ((LM_ERROR,
148 "Unable to bind\n"),
153 return this->make_group (1,
154 id);
158 void
159 Object_Group_Factory_i::unbind_random (const char * id)
161 if (this->random_groups_ == 0)
163 void *tmp_random (0);
165 if (this->mem_pool_->find (random_name_bind,
166 tmp_random) == -1)
167 throw Load_Balancer::no_such_group ();
169 this->random_groups_ = reinterpret_cast <HASH_MAP *> (tmp_random);
172 char *int_id = 0;
174 // Throw an exception if not found in the HASH MAP
175 if (this->random_groups_->find (const_cast<char *> (id),
176 this->mem_pool_) < 0)
177 throw Load_Balancer::no_such_group ();
179 // Unbind the entry
180 this->random_groups_->unbind (const_cast<char *> (id),
181 int_id,
182 this->mem_pool_);
184 // Free the memory from the pool
185 this->mem_pool_->free (int_id - (ACE_OS::strlen (id) + 1));
187 // Change the FLAGS variable
188 if (this->flags_ == 0)
190 void *tmp_flags (0);
192 if (this->mem_pool_->find (flags_name_bind,
193 tmp_flags) == -1)
194 return;
196 this->flags_ = reinterpret_cast <CORBA::Short *> (tmp_flags);
199 // Bump down the flags value
200 this->flags_ -= 2;
203 Load_Balancer::Object_Group_ptr
204 Object_Group_Factory_i::make_group (int random,
205 const char * id)
207 // Store our result here for return.
208 Load_Balancer::Object_Group_var group;
210 // Create an appropriate servant.
211 Object_Group_i *group_servant = 0;
213 // Check to make sure we don't already have a group with the same
214 // <id>.
216 if (random)
218 if (this->random_groups_->find (const_cast<char *> (id),
219 this->mem_pool_) == 0)
220 throw Load_Balancer::duplicate_group ();
222 else
224 if (this->rr_groups_->find (const_cast<char *> (id),
225 this->mem_pool_) == 0)
226 throw Load_Balancer::duplicate_group ();
230 // As we are sure that it is not in the list go ahead and insert it
231 if (random)
232 ACE_NEW_THROW_EX (group_servant,
233 Random_Object_Group (id,
234 this->poa_.in ()),
235 CORBA::NO_MEMORY ());
236 else
237 ACE_NEW_THROW_EX (group_servant,
238 RR_Object_Group (id,
239 this->poa_.in ()),
240 CORBA::NO_MEMORY ());
242 // Register with the poa, begin using ref. counting.
243 group = group_servant->_this ();
245 group_servant->_remove_ref ();
247 CORBA::String_var ior =
248 this->orb_->object_to_string (group.in ());
251 // Calculate and allocate the memory we need to store this name to
252 // object binding.
253 size_t id_len = ACE_OS::strlen (id) + 1;
254 size_t kind_len = ACE_OS::strlen (ior.in ()) + 1;
256 char *ptr = (char *) this->mem_pool_->malloc (id_len + kind_len);
258 if (ptr == 0)
259 throw CORBA::NO_MEMORY ();
261 char * id_ptr = ptr;
262 char * ior_ptr = ptr + id_len;
264 ACE_OS::strcpy (id_ptr, id);
265 ACE_OS::strcpy (ior_ptr, ior.in ());
267 // Store the results here
268 CORBA::Long result = 0;
270 // Make an entry in appropriate map of groups.
271 if (random)
273 result = this->random_groups_->bind (id_ptr,
274 ior_ptr,
275 this->mem_pool_);
277 else
279 result = this->rr_groups_->bind (id_ptr,
280 ior_ptr,
281 this->mem_pool_);
285 // Update the value of flags_
286 this->update_flags (random);
288 if (result == -1)
290 // For some reason the bind failed. Free our
291 // dynamically allocated memory.
292 this->mem_pool_->free ((void *) ptr);
293 throw Load_Balancer::duplicate_group ();
296 // Return.
297 ACE_DEBUG ((LM_DEBUG, "Successfully created new group: %s\n", id));
299 return group._retn ();
303 Load_Balancer::Object_Group_ptr
304 Object_Group_Factory_i::resolve (const char * id)
306 #if defined (DOORS_MEASURE_STATS)
307 // Time the calls
308 // Record the entry time.
309 ACE_hrtime_t latency_base = ACE_OS::gethrtime ();
311 #endif /*DOORS_MEASURE_STATS*/
313 // It could be that the Load balancing service could have failed
314 // before the Client tries to invoke this call.. In such a case the
315 // Service should look in to the MMAP file and read in the info
316 // before it can resolve the ID sent by the client.. So we check
317 // whether the class holds the pointer.. If not we look in to the
318 // MMAP file for the relevant info..
319 if (!this->rr_groups_)
321 void *tmp_rr (0);
323 if (this->mem_pool_->find (rr_name_bind,
324 tmp_rr) == 0)
326 this->rr_groups_ = reinterpret_cast <HASH_MAP *> (tmp_rr);
328 else
330 ACE_ERROR_RETURN ((LM_ERROR,
331 ACE_TEXT ("(%N|%l) The factory does not have any references ")
332 ACE_TEXT ("to the group that you have sought \n\n")),
337 if (!this->random_groups_)
339 void *tmp_random (0);
341 if (this->mem_pool_->find (random_name_bind,
342 tmp_random) == 0)
344 this->random_groups_ = reinterpret_cast <HASH_MAP *> (tmp_random);
346 else
348 ACE_ERROR_RETURN ((LM_ERROR,
349 ACE_TEXT ("(%N|%l) The factory does not have any references ")
350 ACE_TEXT ("to the group that you have sought \n\n")),
355 if (!this->flags_)
357 void *tmp_flags (0);
359 this->mem_pool_->find (flags_name_bind,
360 tmp_flags);
361 this->flags_ = reinterpret_cast <CORBA::Short *> (tmp_flags);
363 this->update_objects ();
366 char *ior = 0;
368 if (rr_groups_->find (const_cast<char *> (id),
369 ior,
370 this->mem_pool_) == -1
371 && random_groups_->find (const_cast<char *> (id),
372 ior,
373 this->mem_pool_) == -1)
374 throw Load_Balancer::no_such_group ();
376 CORBA::Object_var objref =
377 this->orb_->string_to_object (ior);
379 Load_Balancer::Object_Group_ptr
380 object_group = Load_Balancer::Object_Group::_narrow (objref.in ());
383 #if defined (DOORS_MEASURE_STATS)
384 // Grab timestamp again.
385 ACE_hrtime_t now = ACE_OS::gethrtime ();
387 this->throughput_.sample (0,
388 now - latency_base);
390 ACE_High_Res_Timer::global_scale_factor_type gsf =
391 ACE_High_Res_Timer::global_scale_factor ();
392 ACE_OS::printf ("*=*=*=*=Aggregated result *=*=*=*=*=\n");
393 this->throughput_.dump_results (ACE_TEXT("Aggregated"), gsf);
395 #endif /*DOORS_MEASURE_STATS*/
397 return object_group;
400 Load_Balancer::Group_List *
401 Object_Group_Factory_i::list_groups (int random)
403 Load_Balancer::Group_List * list;
405 // Figure out the length of the list.
406 CORBA::ULong len;
407 if (random)
408 len = random_groups_->current_size ();
409 else
410 len = rr_groups_->current_size ();
412 // Allocate the list of <len> length.
413 ACE_NEW_THROW_EX (list,
414 Load_Balancer::Group_List (len),
415 CORBA::NO_MEMORY ());
416 list->length (len);
418 // Create an iterator for group structure to populate the list.
419 HASH_MAP::ITERATOR *group_iter;
420 HASH_MAP::ITERATOR random_iter (*(this->random_groups_));
421 HASH_MAP::ITERATOR rr_iter (*(this->rr_groups_));
422 if (random)
423 group_iter = &random_iter;
424 else
425 group_iter = &rr_iter;
427 // Iterate over groups and populate the list.
428 HASH_MAP::ENTRY *hash_entry = 0;
429 for (CORBA::ULong i = 0; i < len; i++)
431 group_iter->next (hash_entry);
432 group_iter->advance ();
434 (*list)[i] = ACE_OS::strdup (hash_entry->ext_id_);
437 return list;
440 Load_Balancer::Group_List *
441 Object_Group_Factory_i::round_robin_groups ()
443 return list_groups (0);
446 Load_Balancer::Group_List *
447 Object_Group_Factory_i::random_groups ()
449 return list_groups (1);
453 void
454 Object_Group_Factory_i::update_flags (int random)
456 //First check whether we have memory for flags_
457 if (!this->flags_)
459 void *tmp_flags (0);
461 if (this->mem_pool_->find (flags_name_bind,
462 tmp_flags) == 0)
464 this->flags_ = reinterpret_cast <CORBA::Short *> (tmp_flags);
466 else
468 void *value =
469 this->mem_pool_->malloc (sizeof (CORBA::Short));
471 if (value == 0)
472 throw CORBA::NO_MEMORY ();
474 this->flags_ = new (value) CORBA::Short (0);
476 // Initialize the variable
477 this->mem_pool_->bind (flags_name_bind,
478 (void *)this->flags_);
482 CORBA::Short val = *(this->flags_);
483 switch (val)
485 case 0:
486 if (random)
487 *(this->flags_) = 2;
488 else
489 *(this->flags_) = 1;
490 break;
491 case 1:
492 if (random)
493 *(this->flags_) = 3;
494 break;
495 case 2:
496 if (!random)
497 *(this->flags_) = 3;
498 break;
502 void
503 Object_Group_Factory_i::update_objects ()
505 // Create an appropriate servant.
506 Object_Group_i * group_servant = 0;
507 Object_Group_i *group_servant_rep = 0;
509 // Check the value of of flags_ & do the instantiation and
510 // registration
512 switch (*(this->flags_))
514 case 1:
515 ACE_NEW_THROW_EX (group_servant,
516 RR_Object_Group ("Round Robin group",
517 this->poa_.in ()),
518 CORBA::NO_MEMORY ());
519 group_servant->_this ();
520 break;
522 case 2:
523 ACE_NEW_THROW_EX (group_servant,
524 Random_Object_Group ("Random group",
525 this->poa_.in ()),
526 CORBA::NO_MEMORY ());
527 group_servant->_this ();
528 break;
529 case 3:
530 ACE_NEW_THROW_EX (group_servant_rep,
531 Random_Object_Group ("Random group",
532 this->poa_.in ()),
533 CORBA::NO_MEMORY ());
534 group_servant_rep->_this ();
536 ACE_NEW_THROW_EX (group_servant,
537 RR_Object_Group ("Round Robin group",
538 this->poa_.in ()),
539 CORBA::NO_MEMORY ());
540 group_servant->_this ();
541 break;
547 Object_Group_i::Object_Group_i (const char * id,
548 PortableServer::POA_ptr poa)
549 :poa_ (PortableServer::POA::_duplicate (poa)),
550 member_id_list_ (0),
551 members_ (0),
552 id_ (id),
553 allocator_ (0)
555 if (!this->allocator_)
557 ACE_MMAP_Memory_Pool::OPTIONS options (ACE_DEFAULT_BASE_ADDR);
558 ACE_NEW (this->allocator_,
559 ALLOCATOR ("Mem_Pool",
560 "Mem_Pool",
561 &options));
566 Object_Group_i::~Object_Group_i ()
568 // Need to delete all the items from the member_id_list, to avoid
569 // memory leaks.
570 Object_Group_i::ITERATOR iter (*member_id_list_);
574 delete (iter.next ());
575 } while (iter.advance ());
577 delete this->allocator_;
581 PortableServer::POA_ptr
582 Object_Group_i::_default_POA ()
584 return PortableServer::POA::_duplicate (this->poa_.in ());
588 char *
589 Object_Group_i::id ()
591 return CORBA::string_dup (id_.c_str ());
594 void
595 Object_Group_i::bind (const Load_Balancer::Member & member)
597 if (this->members_ == 0)
599 ACE_CString id = this->id ();
601 id += server_id_name_bind;
603 void *tmp_members (0);
605 if (this->allocator_->find (id.c_str (), tmp_members) == 0)
607 this->members_ = reinterpret_cast <HASH_MAP *> (tmp_members);
609 else
611 void *hash_map = this->allocator_->malloc (sizeof (HASH_MAP));
613 if (hash_map == 0)
614 throw CORBA::NO_MEMORY ();
616 this->members_ = new (hash_map) HASH_MAP (this->allocator_);
618 // Bind it in the mem pool with a name
619 if (this->allocator_->bind (id.c_str (),
620 (void *)this->members_) != 0)
622 ACE_ERROR ((LM_ERROR,
623 "Unable to bind\n"));
628 // Check whether the element already exists..
629 if (this->members_->find (const_cast<char *> ((const char *) member.id),
630 this->allocator_) == 0)
631 throw Load_Balancer::duplicate_member ();
633 size_t id_len = ACE_OS::strlen (member.id) + 1;
634 size_t ref_len = ACE_OS::strlen (member.obj) + 1;
636 char *mem_alloc = (char *)this->allocator_->malloc (id_len + ref_len);
638 if (mem_alloc == 0)
639 throw CORBA::NO_MEMORY ();
641 char **id_ptr = (char **)this->allocator_->malloc (sizeof (char *));
642 *id_ptr = mem_alloc;
643 char *ior_ptr = mem_alloc + id_len;
645 ACE_OS::strcpy (*id_ptr, member.id);
646 ACE_OS::strcpy (ior_ptr, member.obj);
649 // Insert new member into <members_> and check for duplicates/failures.
650 int result = this->members_->trybind (*id_ptr,
651 ior_ptr);
653 if (result == 1)
654 throw Load_Balancer::duplicate_member ();
655 else if (result == -1)
656 throw CORBA::INTERNAL ();
658 // Search the list first from the mem mapp pool and then Insert new
659 // member's id into <member_id_list_>.
661 ACE_CString id = dll_name_bind;
662 id += this->id ();
665 void *tmp_id_list (0);
667 if (this->allocator_->find (id.c_str (),
668 tmp_id_list)
669 == 0)
671 this->member_id_list_ = reinterpret_cast <LIST *> (tmp_id_list);
673 else
675 void *dll_list = this->allocator_->malloc (sizeof (LIST));
677 if (dll_list == 0)
678 throw CORBA::NO_MEMORY ();
680 this->member_id_list_ = new (dll_list) LIST (this->allocator_);
682 // Bind it in the mem pool with a name
683 if (this->allocator_->bind (id.c_str (),
684 (void *)this->member_id_list_) != 0)
686 ACE_ERROR ((LM_ERROR,
687 "Unable to bind\n"));
688 return;
692 if (member_id_list_->insert_tail (id_ptr) == 0)
693 throw CORBA::NO_MEMORY ();
695 // Theoretically, we should deal with memory failures more
696 // thoroughly. But, practically, the whole system is going to be
697 // hosed anyways ...
700 void
701 Object_Group_i::unbind (const char * id)
703 // Check whether the this->member_ is NULL
704 if (this->members_ == 0)
706 ACE_CString id = this->id ();
708 id += server_id_name_bind;
710 void *tmp_members (0);
712 if (this->allocator_->find (id.c_str (),
713 tmp_members) == -1)
715 throw Load_Balancer::no_such_member ();
718 this->members_ = reinterpret_cast <HASH_MAP *> (tmp_members);
720 // Check to make sure we have it.
721 if (this->members_->find (const_cast<char *> (id),
722 this->allocator_) == -1)
723 throw Load_Balancer::no_such_member ();
725 // Remove all entries for this member.
726 this->members_->unbind (const_cast<char *> (id),
727 this->allocator_);
729 if (this->member_id_list_ == 0)
731 ACE_CString id = dll_name_bind;
732 id += this->id ();
734 void *tmp_id_list (0);
736 if (this->allocator_->find (id.c_str (),
737 tmp_id_list)
738 == -1)
739 throw Load_Balancer::no_such_member ();
741 this->member_id_list_ = reinterpret_cast <LIST *> (tmp_id_list);
745 Object_Group_i::ITERATOR iter (*(this->member_id_list_));
747 while (ACE_OS::strcmp (id,*(iter.next ())))
748 iter.advance ();
750 this->allocator_->free ((void *) iter.next ());
752 iter.remove ();
755 char *
756 Object_Group_i::resolve_with_id (const char * id)
758 CORBA::String_var ior;
761 if (this->members_->find (const_cast<char *> (id),
762 ior.out (), this->allocator_) == -1)
763 throw Load_Balancer::no_such_member ();
765 char *retn_ptr = CORBA::string_dup (ior.in ());
767 return retn_ptr;
770 Load_Balancer::Member_ID_List *
771 Object_Group_i::members ()
773 Load_Balancer::Member_ID_List * list = 0;
775 this->read_from_memory ();
777 // Figure out the length of the list.
778 CORBA::ULong len = this->members_->current_size ();
780 // Allocate the list of <len> length.
781 ACE_NEW_THROW_EX (list,
782 Load_Balancer::Member_ID_List (len),
783 CORBA::NO_MEMORY ());
784 list->length (len);
786 // Create an iterator for <member_id_list_> to populate the list.
787 Object_Group_i::ITERATOR id_iter (*this->member_id_list_);
789 char **item = 0;
790 // Iterate over groups and populate the list.
791 for (CORBA::ULong i = 0; i < len; i++)
793 this->member_id_list_->get (item);
794 (*list)[i] = *(id_iter.next ());
795 id_iter.advance ();
798 return list;
801 void
802 Object_Group_i::destroy ()
804 // Deregister with POA.
805 PortableServer::POA_var poa =
806 this->_default_POA ();
808 PortableServer::ObjectId_var id =
809 poa->servant_to_id (this);
811 poa->deactivate_object (id.in ());
814 void
815 Object_Group_i::read_from_memory ()
817 // Sanity check needs to be done in all the places
818 ACE_CString id = this->id ();
820 if (!this->members_)
822 id += server_id_name_bind;
824 void *tmp_members (0);
826 if (this->allocator_->find (id.c_str (),
827 tmp_members) == 0)
829 this->members_ = reinterpret_cast <HASH_MAP *> (tmp_members);
831 else
833 ACE_ERROR ((LM_ERROR,
834 "Unable to find tha HASH MAP in the MMAP file\n"));
839 if (!this->member_id_list_)
841 id = dll_name_bind;
842 id += this->id ();
844 void *tmp_id_list (0);
846 if (this->allocator_->find (id.c_str (),
847 tmp_id_list) == 0)
849 this->member_id_list_ = reinterpret_cast <LIST *> (tmp_id_list);
851 else
853 ACE_ERROR ((LM_ERROR,
854 "Unable to find tha HASH MAP in the MMAP file\n"));
861 Random_Object_Group::Random_Object_Group (const char *id,
862 PortableServer::POA_ptr poa)
863 : Object_Group_i (id, poa)
865 // Seed the random number generator.
866 ACE_OS::srand (static_cast<u_int> (ACE_OS::time ()));
869 char *
870 Random_Object_Group::resolve ()
872 this->read_from_memory ();
874 size_t group_size = this->members_->current_size ();
875 if (group_size == 0)
876 throw Load_Balancer::no_such_member ();
878 // Generate random number in the range [0, group_size - 1]
879 size_t member = ACE_OS::rand() % group_size;
881 // Get the id of the member to return to the client.
882 char **id = 0;
883 this->member_id_list_->get (id, member);
884 ACE_DEBUG ((LM_DEBUG, "In Random Group resolved to: %s\n",
885 *id));
887 // Return the object reference corresponding to the found id to the
888 // client.
889 char *objref = 0;
890 this->members_->find (*id,
891 objref,
892 this->allocator_);
893 char *string_ptr = CORBA::string_dup (objref);
894 return string_ptr;
897 RR_Object_Group::RR_Object_Group (const char *id,
898 PortableServer::POA_ptr poa)
899 : Object_Group_i (id, poa),
900 next_ (0)
904 char *
905 RR_Object_Group::resolve ()
907 char *objref = 0;
909 this->read_from_memory ();
911 size_t group_size = this->members_->current_size ();
912 if (group_size == 0)
913 throw Load_Balancer::no_such_member ();
915 // Get the id of the member to return to the client.
916 char **id = 0;
917 this->member_id_list_->get (id, next_);
918 ACE_DEBUG ((LM_DEBUG,
919 "In RR Group resolved to: %s\n", *id));
921 // Adjust <next_> for the next invocation.
922 next_ = (next_ + 1) % group_size;
925 // Return the object reference corresponding to the found id to the client.
926 if (this->members_->find (*id,
927 objref,
928 this->allocator_) == -1)
929 throw CORBA::INTERNAL ();
931 char *retn_ptr = CORBA::string_dup (objref);
933 return retn_ptr;
936 void
937 RR_Object_Group::unbind (const char *id)
939 if (this->members_ == 0)
941 ACE_CString id = this->id ();
943 id += server_id_name_bind;
945 void *tmp_members (0);
947 if (this->allocator_->find (id.c_str (),
948 tmp_members) == -1)
950 throw Load_Balancer::no_such_member ();
953 this->members_ = reinterpret_cast <HASH_MAP *> (tmp_members);
956 // Check to make sure we have it.
957 if (this->members_->find (const_cast<char *> (id),
958 this->allocator_) == -1)
959 throw Load_Balancer::no_such_member ();
961 // Remove all entries for this member.
962 this->members_->unbind (const_cast<char *> (id),
963 this->allocator_);
965 // As we remove the id from the <member_id_list>, we note the
966 // position of the id in the list.
967 if (this->member_id_list_ == 0)
969 ACE_CString id = dll_name_bind;
970 id += this->id ();
972 void *tmp_id_list (0);
974 if (this->allocator_->find (id.c_str (),
975 tmp_id_list)
976 == -1)
977 throw Load_Balancer::no_such_member ();
979 this->member_id_list_ = reinterpret_cast <LIST *> (tmp_id_list);
982 size_t position = 0;
983 Object_Group_i::ITERATOR iter (*member_id_list_);
984 while (ACE_OS::strcmp (id ,*(iter.next ())))
986 iter.advance ();
987 position++;
989 this->allocator_->free (iter.next ());
990 iter.remove ();
992 size_t curr_size = this->members_->current_size ();
994 // Update <next_> if necessary to reflect the deletion.
995 if (position < next_)
996 this->next_--;
997 else if (curr_size == 0)
998 this->next_ = 0;
999 else if (position == next_)
1000 this->next_ = next_ % (this->members_->current_size ());