HttpTransact::handle_cache_write_lock(State* s)
{
  bool remove_ims = false;

  ink_assert(s->cache_info.action == CACHE_PREPARE_TO_DELETE ||
             s->cache_info.action == CACHE_PREPARE_TO_UPDATE || s->cache_info.action == CACHE_PREPARE_TO_WRITE);

  switch (s->cache_info.write_lock_state) {
  case CACHE_WL_SUCCESS:
    // We were able to get the lock for the URL vector in the cache
    SET_UNPREPARE_CACHE_ACTION(s->cache_info);
    break;
  case CACHE_WL_FAIL:
    // No write lock, ignore the cache and proxy only;
    // FIX: Should just serve from cache if this is a revalidate
    s->cache_info.action = CACHE_DO_NO_ACTION;
    s->cache_info.write_status = CACHE_WRITE_LOCK_MISS;
    remove_ims = true;
    break;
  case CACHE_WL_READ_RETRY:
    //  Write failed but retried and got a vector to read
    //  We need to clean up our state so that transact does
    //  not assert later on.  Then handle the open read hit
    //
    s->request_sent_time = UNDEFINED_TIME;
    s->response_received_time = UNDEFINED_TIME;
    s->cache_info.action = CACHE_DO_LOOKUP;
    remove_ims = true;
    SET_VIA_STRING(VIA_DETAIL_CACHE_TYPE, VIA_DETAIL_CACHE);
    break;
  case CACHE_WL_INIT:
  default:
    ink_release_assert(0);
    break;
  }

  // Since we've already built the server request and we can't get the write
  //  lock we need to remove the ims field from the request since we're
  //  ignoring the cache.  If their is a client ims field, copy that since
  //  we're tunneling response anyway
  if (remove_ims) {
    s->hdr_info.server_request.field_delete(MIME_FIELD_IF_MODIFIED_SINCE, MIME_LEN_IF_MODIFIED_SINCE);
    s->hdr_info.server_request.field_delete(MIME_FIELD_IF_NONE_MATCH, MIME_LEN_IF_NONE_MATCH);
    MIMEField *c_ims = s->hdr_info.client_request.field_find(MIME_FIELD_IF_MODIFIED_SINCE, MIME_LEN_IF_MODIFIED_SINCE);
    MIMEField *c_inm = s->hdr_info.client_request.field_find(MIME_FIELD_IF_NONE_MATCH, MIME_LEN_IF_NONE_MATCH);

    if (c_ims) {
      int len;
      const char *value = c_ims->value_get(&len);
      s->hdr_info.server_request.value_set(MIME_FIELD_IF_MODIFIED_SINCE, MIME_LEN_IF_MODIFIED_SINCE, value, len);
    }
    if (c_inm) {
      int len;
      const char *value = c_inm->value_get(&len);
      s->hdr_info.server_request.value_set(MIME_FIELD_IF_NONE_MATCH, MIME_LEN_IF_NONE_MATCH, value, len);
    }
  }

  if (s->cache_info.write_lock_state == CACHE_WL_READ_RETRY) {
    DebugTxn("http_error", "calling hdr_info.server_request.destroy");
    s->hdr_info.server_request.destroy();
    HandleCacheOpenReadHitFreshness(s);
  } else {
    StateMachineAction_t next;
    if (s->stale_icp_lookup == false) {
      next = how_to_open_connection(s);
      if (next == SM_ACTION_ORIGIN_SERVER_OPEN || next == SM_ACTION_ORIGIN_SERVER_RAW_OPEN) {
        s->next_action = next;
        TRANSACT_RETURN(next, NULL);
      } else {
        // hehe!
        s->next_action = next;
        ink_assert(s->next_action == SM_ACTION_DNS_LOOKUP);
        return;
      }
    } else {
      next = SM_ACTION_ICP_QUERY;
    }

    TRANSACT_RETURN(next, NULL);
  }
}
HttpTransact::handle_cache_write_lock(State* s)
{
  bool remove_ims = false;

  ink_assert(s->cache_info.action == CACHE_PREPARE_TO_DELETE ||
             s->cache_info.action == CACHE_PREPARE_TO_UPDATE || s->cache_info.action == CACHE_PREPARE_TO_WRITE);

  switch (s->cache_info.write_lock_state) {
  case CACHE_WL_SUCCESS:
     
    SET_UNPREPARE_CACHE_ACTION(s->cache_info);
    break;
  case CACHE_WL_FAIL:
     
     
    s->cache_info.action = CACHE_DO_NO_ACTION;
    s->cache_info.write_status = CACHE_WRITE_LOCK_MISS;
    remove_ims = true;
    break;
  case CACHE_WL_READ_RETRY:
     
     
     
     
    s->request_sent_time = UNDEFINED_TIME;
    s->response_received_time = UNDEFINED_TIME;
    s->cache_info.action = CACHE_DO_LOOKUP;
    remove_ims = true;
    SET_VIA_STRING(VIA_DETAIL_CACHE_TYPE, VIA_DETAIL_CACHE);
    break;
  case CACHE_WL_INIT:
  default:
    ink_release_assert(0);
    break;
  }

   
   
   
   
  if (remove_ims) {
    s->hdr_info.server_request.field_delete(MIME_FIELD_IF_MODIFIED_SINCE, MIME_LEN_IF_MODIFIED_SINCE);
    s->hdr_info.server_request.field_delete(MIME_FIELD_IF_NONE_MATCH, MIME_LEN_IF_NONE_MATCH);
    MIMEField *c_ims = s->hdr_info.client_request.field_find(MIME_FIELD_IF_MODIFIED_SINCE, MIME_LEN_IF_MODIFIED_SINCE);
    MIMEField *c_inm = s->hdr_info.client_request.field_find(MIME_FIELD_IF_NONE_MATCH, MIME_LEN_IF_NONE_MATCH);

    if (c_ims) {
      int len;
      const char *value = c_ims->value_get(&len);
      s->hdr_info.server_request.value_set(MIME_FIELD_IF_MODIFIED_SINCE, MIME_LEN_IF_MODIFIED_SINCE, value, len);
    }
    if (c_inm) {
      int len;
      const char *value = c_inm->value_get(&len);
      s->hdr_info.server_request.value_set(MIME_FIELD_IF_NONE_MATCH, MIME_LEN_IF_NONE_MATCH, value, len);
    }
  }

  if (s->cache_info.write_lock_state == CACHE_WL_READ_RETRY) {
    DebugTxn("http_error", "calling hdr_info.server_request.destroy");
    s->hdr_info.server_request.destroy();
    HandleCacheOpenReadHitFreshness(s);
  } else {
    StateMachineAction_t next;
    if (s->stale_icp_lookup == false) {
      next = how_to_open_connection(s);
      if (next == SM_ACTION_ORIGIN_SERVER_OPEN || next == SM_ACTION_ORIGIN_SERVER_RAW_OPEN) {
        s->next_action = next;
        TRANSACT_RETURN(next, NULL);
      } else {
         
        s->next_action = next;
        ink_assert(s->next_action == SM_ACTION_DNS_LOOKUP);
        return;
      }
    } else {
      next = SM_ACTION_ICP_QUERY;
    }

    TRANSACT_RETURN(next, NULL);
  }
}