接口:
class DeviceDetectNotifier
{
public:
virtual int DeviceEvent(int event, char* dev_name) = 0;
virtual ~DeviceDetectNotifier() {};
};
class DeviceDetecter
{
public:
static DeviceDetecter* getInstence();
virtual int RegisterNotifier(char* deviceName, DeviceDetectNotifier* notifier) = 0;
virtual ~DeviceDetecter(){};
};
测试代码:
bool run = 1;
bool devExist=0;
pthread_mutex_t mDeviceMutex;
pthread_cond_t mDeviceCond;
char aoaName[64] = {0};
char aoaPath[64] = {0};
class AOADeviceDetectNotifier:public DeviceDetectNotifier
{
public:
virtual int DeviceEvent(int event, char* dev_name)
{
pthread_mutex_lock(&mDeviceMutex);
if(event)
{
devExist = true;
memcpy(aoaName,dev_name,strlen(dev_name));
pthread_cond_signal(&mDeviceCond);
}
else
{
memcpy(aoaName,dev_name,strlen(dev_name));
devExist = false;
}
pthread_mutex_unlock(&mDeviceMutex );
printf("DeviceEvent :%d aoaName:%s \n",event,aoaName);
};
void* dataRevCbk(void* pData,int len);
~AOADeviceDetectNotifier(){}
};
int perDetectDevice(char* dev)
{
int ret = 0;
if(access(dev,F_OK)==0)
{
printf("%s is exist!\n",dev);
ret = 1;
}
return ret;
}
void* devDetectThread(void* parm)
{
while(run)
{
pthread_mutex_lock(&mDeviceMutex);
if(!devExist)
{
pthread_cond_wait(&mDeviceCond, &mDeviceMutex);
}
pthread_mutex_unlock(&mDeviceMutex );
if(strlen(aoaPath)<=0)
{
sprintf(aoaPath,"%s%s","/dev/",aoaName);
}
char* testStr = "hello.";
char readbuf[100]={0};
int error = 0;
int fd = open(aoaPath,O_RDWR);
if(fd<0)
{
printf("AOARWThread open :%s failed.\n",aoaName);
return NULL;
}
}
}
int main(int argc, char* argv[])
{
AOADeviceDetectNotifier aoaNotifier;
AOADeviceDetectNotifier eapNotifier;
DeviceDetecter* p =DeviceDetecter::getInstence();
p->RegisterNotifier("aoa",&aoaNotifier);
char* dev = "/dev/aoa-skel0";
if(perDetectDevice(dev))
{
devExist=1;
sprintf(aoaPath,"%s",dev);
}
pthread_t tid;
pthread_create(&tid, NULL, devDetectThread, NULL);
pthread_join(tid, NULL);
//p->RegisterNotifier("usbmisc",&usbmiscNotifier);
}
实现:
class DeviceDetecterImpl: public DeviceDetecter
{
public:
static DeviceDetecterImpl* getInstence();
virtual int RegisterNotifier(char* deviceName, DeviceDetectNotifier* notifier);
DeviceDetecterImpl();
virtual ~DeviceDetecterImpl();
private:
void DetectThread();
void startDecodeThread();
void stopDecodeThread();
static void* detectThread(void* param);
std::map<char*, DeviceDetectNotifier*> notifierMap;
//std::thread detectThread;
bool detectThreadRun;
pthread_t mThread;
pthread_mutex_t mDetectMutex;
pthread_cond_t mDetectCond;
};
static std::mutex mtx;
static DeviceDetecterImpl* gDeviceDetecterImpl;
DeviceDetecter* DeviceDetecter::getInstence()
{
return DeviceDetecterImpl::getInstence();
}
DeviceDetecterImpl* DeviceDetecterImpl::getInstence()
{
if (NULL == gDeviceDetecterImpl)
{
mtx.lock();
if (NULL == gDeviceDetecterImpl)
{
gDeviceDetecterImpl = new DeviceDetecterImpl();
}
mtx.unlock();
}
return gDeviceDetecterImpl;
}
void DeviceDetecterImpl::DetectThread()
{
struct sockaddr_nl client;
struct timeval tv;
int CppLive, rcvlen, ret;
fd_set fds;
int buffersize = 1024;
CppLive = socket(AF_NETLINK, SOCK_RAW, NETLINK_KOBJECT_UEVENT);
memset(&client, 0, sizeof(client));
client.nl_family = AF_NETLINK;
client.nl_pid = getpid();
client.nl_groups = 1; /* receive broadcast message*/
setsockopt(CppLive, SOL_SOCKET, SO_RCVBUF, &buffersize, sizeof(buffersize));
bind(CppLive, (struct sockaddr*)&client, sizeof(client));
char buf[UEVENT_BUFFER_SIZE] = { 0 };
while (detectThreadRun)
{
if(notifierMap.empty())
{
usleep(10*1000);
}
FD_ZERO(&fds);
FD_SET(CppLive, &fds);
tv.tv_sec = 0;
tv.tv_usec = 100 * 1000;
ret = select(CppLive + 1, &fds, NULL, NULL, &tv);
if (ret < 0)
continue;
if (!(ret > 0 && FD_ISSET(CppLive, &fds)))
continue;
/* receive data */
rcvlen = recv(CppLive, &buf, sizeof(buf), 0);
if (rcvlen > 0)
{
if (!strncmp(buf, "add", 3))
{
map<char*, DeviceDetectNotifier*>::iterator iter;
for(iter = notifierMap.begin(); iter != notifierMap.end(); iter++)
{
char* pAoa = strstr(buf, iter->first);
if (pAoa != NULL)
{
DeviceDetectNotifier* p = iter->second;
p->DeviceEvent(1,pAoa);
}
}
}
else if (!strncmp(buf, "rem", 3))
{
map<char*, DeviceDetectNotifier*>::iterator iter;
for(iter = notifierMap.begin(); iter != notifierMap.end(); iter++)
{
char* pAoa = strstr(buf, iter->first);
if (pAoa != NULL)
{
DeviceDetectNotifier* p = iter->second;
p->DeviceEvent(0,pAoa);
}
}
}
}
}
close(CppLive);
return;
}
DeviceDetecterImpl::DeviceDetecterImpl()
{
detectThreadRun = true;
startDecodeThread();
// detectThread = std::thread(&DeviceDetecterImpl::DetectThread,gDeviceDetecterImpl);
// detectThread.detach();
}
void* DeviceDetecterImpl::detectThread(void* param)
{
DeviceDetecterImpl* pThis = static_cast<DeviceDetecterImpl*>(param);
if (NULL != pThis)
{
pThis->DetectThread();
}
else
{
printf(" there is no object for MicRecordThread!\n");
}
}
void DeviceDetecterImpl::startDecodeThread()
{
int result = pthread_create(&mThread, NULL, detectThread, (void*)this);
if (result != 0)
{
printf("Create pthread error!\n");
}
}
void DeviceDetecterImpl::stopDecodeThread()
{
detectThreadRun = false;
int ret = pthread_join(mThread, NULL);
printf("pthread_join ret:%d \n", ret);
}
DeviceDetecterImpl::~DeviceDetecterImpl()
{
stopDecodeThread();
//detectThread.join();
}
int DeviceDetecterImpl::RegisterNotifier(char* deviceName, DeviceDetectNotifier* notifier)
{
notifierMap.insert(std::pair<char*, DeviceDetectNotifier*>(deviceName, notifier));
return 0;
}