the NetHandler is init at "void initialize_thread_for_net(EThread *thread)".

{code}
260 void
261 initialize_thread_for_net(EThread *thread)
262 {
263   new ((ink_dummy_for_new *)get_NetHandler(thread)) NetHandler();
264   new ((ink_dummy_for_new *)get_PollCont(thread))
PollCont(thread->mutex, get_NetHandler(thread));
265   get_NetHandler(thread)->mutex = new_ProxyMutex();
266   PollCont *pc = get_PollCont(thread);
267   PollDescriptor *pd = pc->pollDescriptor;
268
269   thread->schedule_imm(get_NetHandler(thread));
{code}

the NetHandler object is allocated from thread private data by Line 263.
and its mutex is assigned by Line 265.

I'm searching all the ATS code, only the UnixNetVConnection::reenable()
would access enable_list and ready_list.

the enable_list is atomic list. it's lock free.
but any operation on ready_list should get mutex locked first.

{code}
 783 void
 784 UnixNetVConnection::reenable(VIO *vio)
 785 {
 786   if (STATE_FROM_VIO(vio)->enabled)
 787     return;
 788   set_enabled(vio);
 789   if (!thread)
 790     return;
 791   EThread *t = vio->mutex->thread_holding;
 792   ink_assert(t == this_ethread());
 793   ink_assert(!closed);
 794   if (nh->mutex->thread_holding == t) {  // locked
 795     if (vio == &read.vio) {
 796       ep.modify(EVENTIO_READ);
 797       ep.refresh(EVENTIO_READ);
 798       if (read.triggered)
 799         nh->read_ready_list.in_or_enqueue(this);
 800       else
 801         nh->read_ready_list.remove(this);
 802     } else {
 803       ep.modify(EVENTIO_WRITE);
 804       ep.refresh(EVENTIO_WRITE);
 805       if (write.triggered)
 806         nh->write_ready_list.in_or_enqueue(this);
 807       else
 808         nh->write_ready_list.remove(this);
 809     }
 810   } else {  // non-locked
 811     MUTEX_TRY_LOCK(lock, nh->mutex, t);  // try lock
 812     if (!lock.is_locked()) {
 813       if (vio == &read.vio) {
 814         if (!read.in_enabled_list) {
 815           read.in_enabled_list = 1;
 816           nh->read_enable_list.push(this);
 817         }
 818       } else {
 819         if (!write.in_enabled_list) {
 820           write.in_enabled_list = 1;
 821           nh->write_enable_list.push(this);
 822         }
 823       }
 824       if (nh->trigger_event && nh->trigger_event->ethread->signal_hook)
 825
nh->trigger_event->ethread->signal_hook(nh->trigger_event->ethread);
 826     } else {  // locked
 827       if (vio == &read.vio) {
 828         ep.modify(EVENTIO_READ);
 829         ep.refresh(EVENTIO_READ);
 830         if (read.triggered)
 831           nh->read_ready_list.in_or_enqueue(this);
 832         else
 833           nh->read_ready_list.remove(this);
 834       } else {
 835         ep.modify(EVENTIO_WRITE);
 836         ep.refresh(EVENTIO_WRITE);
 837         if (write.triggered)
 838           nh->write_ready_list.in_or_enqueue(this);
 839         else
 840           nh->write_ready_list.remove(this);
 841       }
 842     }
 843   }
 844 }
{code}

these Lines from 795 to 890 and these Lines from 827 to 841 are totally
same.

what's the value of Lines from 794 to 810 ?

why not do "get_NetHandler(thread)->mutex = thread->mutex;" ?

the reenable() could be simple and clear if set nh->mutex to thread-mutex:
{code}
783 void
 784 UnixNetVConnection::reenable(VIO *vio)
 785 {
 786   if (STATE_FROM_VIO(vio)->enabled)
 787     return;
 788   set_enabled(vio);
 789   if (!thread)
 790     return;
 791   EThread *t = vio->mutex->thread_holding;
 792   ink_assert(t == this_ethread());
 793   ink_assert(!closed);

 811     MUTEX_TRY_LOCK(lock, nh->mutex, t);  // try lock
 812     if (!lock.is_locked()) {
 813       if (vio == &read.vio) {
 814         if (!read.in_enabled_list) {
 815           read.in_enabled_list = 1;
 816           nh->read_enable_list.push(this);
 817         }
 818       } else {
 819         if (!write.in_enabled_list) {
 820           write.in_enabled_list = 1;
 821           nh->write_enable_list.push(this);
 822         }
 823       }
 824       if (nh->trigger_event && nh->trigger_event->ethread->signal_hook)
 825
nh->trigger_event->ethread->signal_hook(nh->trigger_event->ethread);
 826     } else {  // locked
 827       if (vio == &read.vio) {
 828         ep.modify(EVENTIO_READ);
 829         ep.refresh(EVENTIO_READ);
 830         if (read.triggered)
 831           nh->read_ready_list.in_or_enqueue(this);
 832         else
 833           nh->read_ready_list.remove(this);
 834       } else {
 835         ep.modify(EVENTIO_WRITE);
 836         ep.refresh(EVENTIO_WRITE);
 837         if (write.triggered)
 838           nh->write_ready_list.in_or_enqueue(this);
 839         else
 840           nh->write_ready_list.remove(this);
 841       }
 842     }

 844 }
{code}

Thanks

B/R

Oknet Xu

Reply via email to