This commit is contained in:
aixianling
2025-01-09 17:45:40 +08:00
commit 5c9f1dae4a
3482 changed files with 1146531 additions and 0 deletions

View File

@@ -0,0 +1,151 @@
#ifndef _SENDPACK_POOL_H_
#define _SENDPACK_POOL_H_
/************************************************************************
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݰ<EFBFBD><DDB0><EFBFBD><EFBFBD>л<EFBFBD><D0BB><EFBFBD><EFBFBD><EFBFBD>
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ּ<EFBFBD><D6BC>
1<><31><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݰ<EFBFBD><DDB0>ķ<EFBFBD><C4B7>ͣ<EFBFBD><CDA3><EFBFBD><EFBFBD><EFBFBD><E1BDBB><EFBFBD>ݰ<EFBFBD><DDB0><EFBFBD>˳<EFBFBD><CBB3><EFBFBD><EFBFBD><EFBFBD>з<EFBFBD><D0B7>ͣ<EFBFBD>
2<><32>ͨ<EFBFBD><CDA8><EFBFBD><EFBFBD><EFBFBD>ݰ<EFBFBD><DDB0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ķ<EFBFBD>ʽ<EFBFBD><CABD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݰ<EFBFBD><DDB0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݰ<EFBFBD><DDB0><EFBFBD><EFBFBD>ݿ<EFBFBD><DDBF><EFBFBD><EFBFBD>Ŀ<EFBFBD><C4BF><EFBFBD><EFBFBD><EFBFBD>
3<><33>ʹ<EFBFBD><CAB9><EFBFBD>ڴ<EFBFBD><DAB4>أ<EFBFBD><D8A3><EFBFBD>פ<EFBFBD>ڴ棩<DAB4>Ż<EFBFBD><C5BB>ڴ<EFBFBD><DAB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<20><><EFBFBD><EFBFBD>ԭ<EFBFBD><D4AD><EFBFBD><EFBFBD>
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݰ<EFBFBD><DDB0><EFBFBD><EFBFBD><EFBFBD>б<EFBFBD><D0B1>У<EFBFBD><D0A3><EFBFBD><EFBFBD><EFBFBD>ʱѭ<CAB1><D1AD><EFBFBD><EFBFBD><EFBFBD>б<EFBFBD><D0B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>͡<EFBFBD><CDA1><EFBFBD><E1B4A6><EFBFBD><EFBFBD><EFBFBD>͹<EFBFBD><CDB9><EFBFBD><EFBFBD>ж<EFBFBD>һ<EFBFBD><D2BB>
<20><><EFBFBD>ݰ<EFBFBD>ֻ<EFBFBD><D6BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>½<EFBFBD><C2BD><EFBFBD><EFBFBD>´η<C2B4><CEB7><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD>ݰ<EFBFBD>δ<EFBFBD><CEB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<20>IJ<EFBFBD><C4B2>֡<EFBFBD>
ϣ<><CFA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݰ<EFBFBD><DDB0>ĵ<EFBFBD><C4B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>allocSendPacketList<73><74>allocSendPacketList
<20><><EFBFBD><EFBFBD>ȡ<EFBFBD><C8A1>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݰ<EFBFBD><DDB0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݰ<EFBFBD><DDB0><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѱ<EFBFBD><D1B1><EFBFBD><EFBFBD>գ<EFBFBD><D5A3><EFBFBD>ֱ<EFBFBD><D6B1>д<EFBFBD><D0B4><EFBFBD><EFBFBD><EFBFBD>ݡ<EFBFBD><DDA1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>д<EFBFBD><D0B4><EFBFBD><EFBFBD><EFBFBD>ɺ󣬵<C9BA><F3A3ACB5><EFBFBD>flushSendPacket<65><74>flushSendPacketList<73><74><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݰ<EFBFBD><DDB0><EFBFBD>
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ͷ<EFBFBD><CDB6><EFBFBD><EFBFBD>С<EFBFBD>
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݰ<EFBFBD><DDB0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڶ<EFBFBD><DAB6>л<EFBFBD><D0BB><EFBFBD><EFBFBD>ر<EFBFBD><D8B1><EFBFBD><EFBFBD><EFBFBD>ǰ<EFBFBD><EFBFBD><E1BDBB><EFBFBD>ݰ<EFBFBD><DDB0><EFBFBD>
<20><><EFBFBD>ݷ<EFBFBD><DDB7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>sendToSocket<65><74><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ͷ<EFBFBD><CDB6><EFBFBD><EFBFBD>е<EFBFBD><D0B5><EFBFBD><EFBFBD>ݰ<EFBFBD>ͨ<EFBFBD><CDA8>socket<65><74><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͣ<EFBFBD>
<20><>һ<EFBFBD><D2BB>sendToSocket<65>ĵ<EFBFBD><C4B5><EFBFBD><EFBFBD>в<EFBFBD><D0B2><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><E1BDAB><EFBFBD>Ͷ<EFBFBD><CDB6>е<EFBFBD><D0B5><EFBFBD><EFBFBD>ݰ<EFBFBD>ȫ<EFBFBD><C8AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɣ<EFBFBD><C9A3><EFBFBD><EFBFBD><EFBFBD>socket
<20><>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʽ<EFBFBD><CABD><EFBFBD>׽<EFBFBD><D7BD>֡<EFBFBD><D6A1><EFBFBD>һ<EFBFBD>ε<EFBFBD><CEB5><EFBFBD><EFBFBD>޷<EFBFBD><DEB7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݰ<EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>´ε<C2B4><CEB5><EFBFBD><EFBFBD>м<EFBFBD><D0BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͺ<EFBFBD>
<20><><EFBFBD>IJ<EFBFBD><C4B2>֡<EFBFBD>
<20>ܹ<EFBFBD><DCB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ч<EFBFBD>ʵķ<CAB5>ʽ<EFBFBD><CABD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֣<EFBFBD>
1<><31> <20>ڻ<EFBFBD><DABB><EFBFBD><E1BDBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݵ<EFBFBD><DDB5>߳<EFBFBD><DFB3>ڲ<EFBFBD><DAB2><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD>ݰ<EFBFBD><DDB0>б<EFBFBD><D0B1><EFBFBD>ʹ<EFBFBD>ú<EFBFBD><C3BA><EFBFBD>
AllocSendPacketListһ<74><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݰ<EFBFBD><DDB0><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<20><><EFBFBD>ݰ<EFBFBD><DDB0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϻ󣬵<CFBA><F3A3ACB5><EFBFBD>FlushSendPacketListһ<74><D2BB><EFBFBD><EFBFBD>ȫ<EFBFBD><C8AB><EFBFBD>һ<E1BDBB><D2BB>
<20>б<EFBFBD><D0B1>е<EFBFBD><D0B5><EFBFBD><EFBFBD>ݰ<EFBFBD><DDB0><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD>ܹ<EFBFBD><DCB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Է<EFBFBD><D4B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݰ<EFBFBD><DDB0><EFBFBD><EFBFBD><EFBFBD>/<2F><EFBFBD>ĵ<EFBFBD>Ч<EFBFBD><D0A7>Ϊ
<20><><EFBFBD><EFBFBD>/<2F><EFBFBD>ġ<EFBFBD><C4A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϣ<EFBFBD><CFA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>εĻ<CEB5>ȡ<EFBFBD><C8A1><EFBFBD>IJ<EFBFBD><C4B2><EFBFBD><EFBFBD>ϲ<EFBFBD>Ϊһ<CEAA>Σ<EFBFBD>
ʹ<>ô˷<C3B4><CBB7><EFBFBD><EFBFBD><EFBFBD>Ҫע<D2AA><EFBFBD><EFBFBD>ķ<EFBFBD><C4B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݰ<EFBFBD><DDB0>Ķ<EFBFBD><C4B6><EFBFBD><EFBFBD>У<EFBFBD>ÿ<EFBFBD><C3BF><EFBFBD><EFBFBD><EFBFBD>ݰ<EFBFBD><DDB0>Ķ<EFBFBD>д
ƫ<><C6AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ0<CEAA><30>FlushSendPacketList<73><74><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>޸<EFBFBD><DEB8><EFBFBD><E1BDBB><EFBFBD>ݰ<EFBFBD><DDB0>б<EFBFBD>
<20><><EFBFBD>κ<EFBFBD><CEBA><EFBFBD><EFBFBD>ݰ<EFBFBD><DDB0><EFBFBD>ƫ<EFBFBD><C6AB>ָ<EFBFBD>
2<><32> <20><>һ<EFBFBD><D2BB><EFBFBD>ܹ<EFBFBD><DCB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݰ<EFBFBD><DDB0><EFBFBD><EFBFBD><EFBFBD>/<2F><EFBFBD>IJ<EFBFBD><C4B2><EFBFBD>ǰ<EFBFBD><C7B0><EFBFBD>߼<EFBFBD>ѭ<EFBFBD><D1AD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<20><><EFBFBD>֣<EFBFBD><D6A3><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD>ݰ<EFBFBD><DDB0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>еķ<D0B5><C4B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȫ<EFBFBD><C8AB>׷<EFBFBD>ӵ<EFBFBD><D3B5><EFBFBD><EFBFBD><EFBFBD>Ψһ<CEA8><D2BB><EFBFBD><EFBFBD>
<20>ݰ<EFBFBD><DDB0>У<EFBFBD><D0A3><EFBFBD><EFBFBD>ڲ<EFBFBD><DAB2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E1BDBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݰ<EFBFBD><DDB0><EFBFBD><EFBFBD>ܹ<EFBFBD><DCB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Է<EFBFBD><D4B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݰ<EFBFBD><DDB0><EFBFBD><EFBFBD><EFBFBD>/<2F>
<20><>Ч<EFBFBD><D0A7>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݰ<EFBFBD><DDB0><EFBFBD>д<EFBFBD><D0B4><EFBFBD><EFBFBD>ͨ<EFBFBD><CDA8><EFBFBD><EFBFBD><EFBFBD>ݵĴ<DDB5><C4B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϡ<EFBFBD>
************************************************************************/
using namespace container;
using namespace net;
class SendPacketPool
{
typedef Vector<DataPacket*> PacketList;
struct PackCount
{
DataPacket* list_;
int count_;
};
public:
SendPacketPool(const char* name);
~SendPacketPool();
inline DataPacket& AllocSendPack(BaseAllocator* allocator = NULL)
{
DataPacket* pack;
AllocSendPack(NULL, 0, &pack, allocator);
pack->setLength(0);
return *pack;
}
// <20>ŵ<EFBFBD><C5B5><EFBFBD><EFBFBD>Ͷ<EFBFBD><CDB6><EFBFBD><EFBFBD><EFBFBD>
inline void Flush(DataPacket& packet)
{
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݰ<EFBFBD><DDB0>ڴ<EFBFBD><DAB4>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD>ƻ<EFBFBD>
packet._Assert();
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݰ<EFBFBD><DDB0>б<EFBFBD>д<EFBFBD><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E1BDBB><EFBFBD><EFBFBD><EFBFBD>Ͷ<EFBFBD><CDB6>У<EFBFBD><D0A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԭ<EFBFBD><D4AD><EFBFBD>ݰ<EFBFBD><DDB0><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD><D0B6><EFBFBD>
if (packet.getLength() > 0)
{
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݰ<EFBFBD>ƫ<EFBFBD><C6AB>Ϊ0<CEAA><30><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڷ<EFBFBD><DAB7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݵĴ<DDB5><C4B4><EFBFBD><EFBFBD>ݰ<EFBFBD>ͷ<EFBFBD><CDB7><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD>
packet.setPosition(0);
//<2F><><EFBFBD><EFBFBD><EFBFBD>ݰ<EFBFBD>׷<EFBFBD>ӵ<EFBFBD><D3B5><EFBFBD><EFBFBD>Ͷ<EFBFBD><CDB6><EFBFBD><EFBFBD><EFBFBD>
send_list_.append(&packet);
}
else
{
free_list_.lock();
free_list_.add(&packet);
free_list_.unlock();
}
}
void AllocSendPack(PacketList* p_list, int alloc_count, DataPacket** single = NULL, BaseAllocator* allocator = NULL);
inline void Flush(PacketList& packetList)
{
send_list_.appendArray(packetList, packetList.count());
}
void ClearSendList();
size_t SendToSocket(net::BaseSocket& socket);
inline size_t GetPacketCount()
{
send_list_.flush();
return send_list_.count() + send_list_.appendCount();
}
// <20><><EFBFBD><EFBFBD>Ĭ<EFBFBD>ϵ<EFBFBD><CFB5>ڴ<EFBFBD><DAB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĭ<EFBFBD>Ͼ<EFBFBD><CFBE><EFBFBD>pack_allocator_
// ע<><D7A2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̰߳<DFB3>ȫ
inline void SetAllocator(BaseAllocator* alloc)
{
if (!alloc) return;
def_alloc_ = alloc;
}
inline void UseBaseAlloc(bool flag)
{
def_alloc_ = flag ? &base_allocator_ : &pack_allocator_;
}
void FreeAllPackets();
bool IsPackBlocked()
{
return pack_blocked_;
}
// <20><><EFBFBD><EFBFBD><EFBFBD>ͷ<EFBFBD><CDB7>ڴ<EFBFBD>
void GC();
size_t GetAllocCount()
{
return def_alloc_->GetAllocCount();
}
const char* GetName()
{
return pool_name_;
}
private:
BufferAllocator pack_allocator_; //<2F>ڴ<EFBFBD><DAB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
BaseAllocator base_allocator_; //
BaseAllocator* def_alloc_; //
Mutex send_lock_;//<2F><><EFBFBD><EFBFBD><EFBFBD>е<EFBFBD><D0B5><EFBFBD><EFBFBD>ݰ<EFBFBD><DDB0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
Mutex free_lock_; //<2F><><EFBFBD>е<EFBFBD><D0B5><EFBFBD><EFBFBD>ݰ<EFBFBD><DDB0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
int send_idx_;//<2F><><EFBFBD>Ͷ<EFBFBD><CDB6><EFBFBD><EFBFBD>е<EFBFBD><D0B5><EFBFBD>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD>λ<EFBFBD><CEBB>
QueueList<DataPacket*> send_list_;//<2F><><EFBFBD><EFBFBD><EFBFBD>е<EFBFBD><D0B5><EFBFBD><EFBFBD>ݰ<EFBFBD><DDB0><EFBFBD><EFBFBD><EFBFBD>
LockList<DataPacket*> free_list_; //<2F><><EFBFBD>е<EFBFBD><D0B5><EFBFBD><EFBFBD>ݰ<EFBFBD><DDB0><EFBFBD><EFBFBD><EFBFBD>
Vector<PackCount> all_list_;//<2F><><EFBFBD>ݰ<EFBFBD><DDB0>ڴ<EFBFBD><DAB4><EFBFBD>ָ<EFBFBD><D6B8><EFBFBD>б<EFBFBD>
char pool_name_[32];
bool pack_blocked_; // <20>Ƿ<EFBFBD><C7B7>д<EFBFBD><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
};
#endif