///
/// @file Lock.h
/// @brief
/// @author guozhiming
/// @date 2007-04-11
///
#ifndef __LOCK__
#define __LOCK__
#include "def.h"
//定义了信号量锁,还有读写锁;话说我用qt开发,这些锁qt里面都有。可以直接拿来用了
/// @brief 锁的基本操作   1:读操作的时候读锁可以并发 2:写操作的时候,独占操作
class G_Lock
{
    public:
                                                  
        /// @brief 构造函数初始化互斥锁 , 条件变量
        G_Lock();
        /// @brief 析构函数释放互斥锁,和条件变量
        ~G_Lock();
        /// @brief 读锁 readCounter++ , 锁住readCounter
        void rLock();
        /// @brief 解锁 readCounter-- , 如果readCounter = 0 , pthread_cond_signal通知
        void unrLock();
        /// @brief 写锁 如果readCounter不为0一直 pthread_cond_wait等待下去
        void wLock();
        /// @brief 解锁
        void unwLock();
                                              
    private:
        pthread_mutex_t r_Mutex;     ///读锁 ,锁住readCounter
        pthread_mutex_t w_Mutex;     ///锁住同步资源
                                                  
        unsigned long readCounter;             ///条件变量如果为0通知(pthread_cond_signal)
        pthread_cond_t condReadCounter;
};
#endif


///
/// @file Lock.cpp
/// @brief
/// @author guozhiming
/// @date 2007-04-11
//现在是2013年,这家伙07年就写得这代码,我现在看,是否落后呢?
///
#include "Lock.h"
G_Lock::G_Lock()
{
    pthread_mutex_init(&r_Mutex , NULL);
    pthread_mutex_init(&w_Mutex , NULL);
    pthread_cond_init(&condReadCounter , NULL);
    readCounter = 0;
}
G_Lock::~G_Lock()
{
    pthread_mutex_destroy(&r_Mutex);
    pthread_mutex_destroy(&w_Mutex);
    pthread_cond_destroy(&condReadCounter);
}
void G_Lock::rLock()
{
//读写都是配套出现的,没有现成的c库吗?要自己写。读的时候不许写,读靠一个信号量,最大允许多少人同时读。。。
    pthread_mutex_lock(&w_Mutex);   //防止于写操作冲突
    pthread_mutex_lock(&r_Mutex);   //防止readCounter 冲突
    readCounter++;  //只是为了++这个,上面2句下面2句
    pthread_mutex_unlock(&w_Mutex);     ///写解锁
    pthread_mutex_unlock(&r_Mutex);     ///读解锁
//先上锁一遍,再解锁??记得有个try_lock!!!???
}
//什么意思都是先加锁,再解锁。。。
void G_Lock::unrLock()
{
    pthread_mutex_lock(&r_Mutex);      ///读加锁
    readCounter--;
    if(0 == readCounter)
    {
//pthread_cond_t condReadCounter;这样定义的,这也叫信号。。。这个机制还不清楚,一般都用封装好的c++类。。
        pthread_cond_signal(&condReadCounter);    //如果readCounter为0 , 表示已经没有读了,可以写
    }
    pthread_mutex_unlock(&r_Mutex);     ///读解锁
}
//又是先加锁再解锁。。。
void G_Lock::wLock()
{
    pthread_mutex_lock(&w_Mutex);   ///写加锁
    pthread_mutex_lock(&r_Mutex);   ///读加锁
    if(0 == readCounter)   ///防止readCounter = 0而且没有调用过rLock()和unrLock()
    {
        pthread_mutex_unlock(&r_Mutex);    ///读解锁
        return ;
    }
//这是对应上面的那个signal吗?
    pthread_cond_wait(&condReadCounter , &r_Mutex);         //等待readCounter = 0 , 等待期间r_Mutex被解锁,有信号再加锁
    pthread_mutex_unlock(&r_Mutex);       ///读解锁
}
//这个直接解锁,终于明白了
void G_Lock::unwLock()
{
    pthread_mutex_unlock(&w_Mutex);         //写解锁
}



///
/// @file def.h
/// @brief
/// @author guozhiming
/// @date 2007-04-11
///
#ifndef __DEF__
#define __DEF__
#include <iostream>
#include <errno.h>
#include <pthread.h>
#include <time.h>
#include <sys/time.h>
#include <unistd.h>
#include <sys/types.h>
#include <deque>  //哦。有标准的queue,竟然还自己写个。
#include <signal.h>
#include <sys/epoll.h>
#include <fcntl.h>
#include <stdarg.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <map>  //标准c++
using namespace std;
typedef unsigned long ULONG;
/// @brief 为了服务器接收到client的信息把数据和client的套接字连接到一起
struct G_DataSocket
{
    int nSocket;
    void *pStr;
};
#endif



///
/// @file ListenThread.h
/// @brief 服务器监听线程
/// @author guozhiming
/// @date 2007-05-16
///
#ifndef __G_LISTENTHREAD__
#define __G_LISTENTHREAD__
#include "Thread.h"
#include "Socket.h"
#include "ThreadPool.h"
class G_ThreadPool;  //线程池。。
class G_ListenThread : public G_Thread //还有个基类
{
    public:
        /// @brief 构造函数
        G_ListenThread(G_ThreadPool *pool);
        /// @brief 析构函数
        virtual ~G_ListenThread();
        /// @brief
        void Run();   //哦。都是一个run,和qt的线程模式一样。
        /// @brief 服务器帮定端口
        ///
        /// @param nPort 帮定端口
        ///
        /// @return true表示成功 , false表示失败
        bool Bind(unsigned int nPort);
    private:
               
        ///套接口操作的对象
        G_Socket *g_socket;
        G_ThreadPool *g_threadPool;
};
#endif



#include "ListenThread.h"
#include "Log.h"
G_ListenThread::G_ListenThread(G_ThreadPool *pool) : g_threadPool(pool)
{
    g_socket = new G_Socket();
}
G_ListenThread::~G_ListenThread()
{
    if(g_socket)
    {
        delete g_socket;
        g_socket = NULL;
    }
}
void G_ListenThread::Run()
{
    pause();//看不懂,暂停,,什么时候开始。?有信号时,会中断此函数。什么信号,什么时候来?
    debug_output("Listen thread is starting ....\n");
      
    int nSocket;
    while(1)
    {
        if(g_socket->Listen(nSocket))
        {
            debug_output("new client is connecting ....\n");//新的连接?那socket是客户端的socket??
            g_threadPool->pushSocket(nSocket);   ///填加到套接口队列//这里放的是server的socket啊??
            g_threadPool->continues();   ///通知线程池,运行起来,到套接口队列中取套接口
        }
    }
}
bool G_ListenThread::Bind(unsigned int nPort)
{
    if(!g_socket->Bind(nPort))
    {
        debug_output("Bind port %d is faild\n" , nPort);
        return false;
    }
    debug_output("Bind port %d is Successful\n" , nPort);
    continues();
    return true;
}