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